c#等待for循环

问题描述 投票:1回答:2

如果缺少信息,我有一个需要更新的项目列表。但是,我正在打电话给谷歌位置服务。我想知道如果可能的话我如何异步附加必要的Lat&Long信息

我的代码

public static void PullInfo()
{
   foreach (var item in SAPItems)
   {
        if(item.MDM_Latitude == null || item.MDM_Longitude == null)
        {
             var point = GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip);
             item.MDM_Latitude = point.Result.Latitude.ToString();
             item.MDM_Longitude = point.Result.Longitude.ToString();
        }                    
    }

    foreach(var item in SAPItems)
         Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}

private static async Task<MapPoint> GetMapPoint(string add)
{
     var task = Task.Run(() => LocationService.GetLatLongFromAddress(add));
     return await task;
}
c# async-await
2个回答
4
投票

您可以使用多个任务异步获取多个映射点(请注意,它需要将PullInfo()转换为async-await):

public static async Task PullInfo()
{
    // Create tasks to update items with latitude and longitude
    var tasks
        = SAPItems.Where(item => item.Latitude == null || item.Longitude == null)
            .Select(item =>
                GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip)
                    .ContinueWith(pointTask => {
                        item.MDM_Latitude = pointTask.Result.Latitude.ToString();
                        item.MDM_Longitude = pointTask.Result.Longitude.ToString();
                    }));

    // Non-blocking await for tasks completion
    await Task.WhenAll(tasks);

    // Iterate to append Lat and Long
    foreach(var item in SAPItems)
        Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}

private static Task<MapPoint> GetMapPoint(string add)
{
     return Task.Run(() => LocationService.GetLatLongFromAddress(add));
}

如果PullInfo()无法转换为async-await,则可以强制线程等待结果,但它会阻止当前线程:

public static void PullInfo()
{
    // Create tasks to update items with latitude and longitude
    var tasks
        = SAPItems.Where(item => item.Latitude == null || item.Longitude == null)
            .Select(item =>
                GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip)
                    .ContinueWith(pointTask => {
                        item.MDM_Latitude = pointTask.Result.Latitude.ToString();
                        item.MDM_Longitude = pointTask.Result.Longitude.ToString();
                    }));

    // Wait for tasks completion (it will block the current thread)
    Task.WaitAll(tasks.ToArray());

    // Iterate to append Lat and Long
    foreach(var item in SAPItems)
        Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}

private static Task<MapPoint> GetMapPoint(string add)
{
     return Task.Run(() => LocationService.GetLatLongFromAddress(add));
}

运行最后一个代码示例的示例:https://ideone.com/0uXGlG


0
投票

你只需要等待获取数据的调用(注意await是如何从GetMapPoint移动的):

public static async Task PullInfo()
{
   foreach (var item in SAPItems)
   {
        if(item.Latitude == null || item.Longitude == null)
        {
             var point = await GetMapPoint(item.AddressLine1 + " " + item.FiveDigitZip);

             item.MDM_Latitude = point.Latitude.ToString();
             item.MDM_Longitude = point.Longitude.ToString();
        }                    
    }

    foreach(var item in SAPItems)
         Console.WriteLine(item.MDM_Latitude + " " + item.MDM_Longitude);
}

private static Task<MapPoint> GetMapPoint(string add)
{
     var task = Task.Run(() => LocationService.GetLatLongFromAddress(add));
     return task;
}

你不是要修改你的SAPItems系列,只是修改每个项目。获得响应后,您只需更新循环中的当前项即可。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.