c#等待循环

c#等待循环,c#,async-await,C#,Async Await,如果信息丢失,我有一个需要更新的项目列表。然而,我正在打电话给谷歌定位服务公司去做这件事。如果可能的话,我想知道如何异步附加必要的Lat&Long信息 我的代码 public static void PullInfo() { foreach (var item in SAPItems) { if(item.MDM_Latitude == null || item.MDM_Longitude == null) { var poi

如果信息丢失,我有一个需要更新的项目列表。然而,我正在打电话给谷歌定位服务公司去做这件事。如果可能的话,我想知道如何异步附加必要的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;
}
publicstaticvoidpullinfo()
{
foreach(SAPItems中的var项目)
{
如果(item.MDM_纬度==null | | item.MDM_经度==null)
{
变量点=GetMapPoint(item.AddressLine1+“”+item.FiveDigitZip);
item.MDM_Latitude=point.Result.Latitude.ToString();
item.MDM_Longitude=point.Result.Longitude.ToString();
}                    
}
foreach(SAPItems中的var项目)
Console.WriteLine(item.MDM_纬度+“”+item.MDM_经度);
}
私有静态异步任务GetMapPoint(字符串添加)
{
var task=task.Run(()=>LocationService.GetLatLongFromAddress(add));
返回等待任务;
}

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

公共静态异步任务PullInfo()
{
foreach(SAPItems中的var项目)
{
if(item.Latitude==null | | item.Longitude==null)
{
变量点=等待GetMapPoint(item.AddressLine1+“”+item.FiveDigitZip);
item.MDM_Latitude=point.Latitude.ToString();
item.MDM_Longitude=point.Longitude.ToString();
}                    
}
foreach(SAPItems中的var项目)
Console.WriteLine(item.MDM_纬度+“”+item.MDM_经度);
}
私有静态任务GetMapPoint(字符串添加)
{
var task=task.Run(()=>LocationService.GetLatLongFromAddress(add));
返回任务;
}

您没有修改
SAPItems
集合,只修改每个单独的项目。收到响应后,您可以更新循环中的当前项。

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

公共静态异步任务PullInfo()
{
foreach(SAPItems中的var项目)
{
if(item.Latitude==null | | item.Longitude==null)
{
变量点=等待GetMapPoint(item.AddressLine1+“”+item.FiveDigitZip);
item.MDM_Latitude=point.Latitude.ToString();
item.MDM_Longitude=point.Longitude.ToString();
}                    
}
foreach(SAPItems中的var项目)
Console.WriteLine(item.MDM_纬度+“”+item.MDM_经度);
}
私有静态任务GetMapPoint(字符串添加)
{
var task=task.Run(()=>LocationService.GetLatLongFromAddress(add));
返回任务;
}

您没有修改
SAPItems
集合,只修改每个单独的项目。获得响应后,您可以更新循环中的当前项。

您可以通过多个任务异步获得多个映射点(注意,需要将
PullInfo()
转换为异步等待):


最后一个代码示例的运行示例:

您可以通过多个任务异步获取多个映射点(请注意,需要将
PullInfo()
转换为异步等待):



最后一个代码示例的运行示例:

@Rup只需在特定的item对象中设置数字。我更新了问题。为什么在等待
GetMapPoint
函数时使用
.Result
?等待之后,您已经有了数据,只需在那里等待,而不是在
GetMapPoint
中。尝试将列表更改为ConcurrentBag,将foreach更改为Parallel.foreach为什么不能只说
var point=await GetMapPoint(item.AddressLine1+“”+item.FiveDigitZip)@Rup只需设置特定项目对象中的数字。我更新了问题。为什么在等待
GetMapPoint
函数时使用
.Result
?等待之后,您已经有了数据,只需在那里等待,而不是在
GetMapPoint
中。尝试将列表更改为ConcurrentBag,将foreach更改为Parallel.foreach为什么不能只说
var point=await GetMapPoint(item.AddressLine1+“”+item.FiveDigitZip)我已经运行了这个方法,但是我缺少的纬度和经度仍然没有被分配。有什么想法吗?@user3434042第一个还是第二个?是否要更新纬度/经度或MDM_纬度/MDM_经度?tasks.ToArray()将导致枚举被迭代。不需要最后一个foreach循环。我已经运行了这个方法,但是我缺少的纬度和经度仍然没有被指定。有什么想法吗?@user3434042第一个还是第二个?是否要更新纬度/经度或MDM_纬度/MDM_经度?tasks.ToArray()将导致枚举被迭代。不需要最后一个FURACH循环。在循环的中间放置<代码>等待<代码>将编译成一个混乱的状态机,并将破坏预期的逻辑。吉列尔莫给出的答案是这样做的。@Nik你为什么认为它会破坏逻辑?我很抱歉,进一步考虑一下(但我没有测试),它不应该破坏逻辑,但状态机确实编译成比它需要的更复杂的东西。使用ILSpy(或您使用的任何工具)查看您提出的方法与公认答案相比的编译效果。特别是,请查看编译器生成的
MoveNext()
方法。如果要在C#5之前实现这一点,我怀疑有人会试图创造这样的逻辑。对我来说,你也不应该编写没有语法糖就无法编写的代码……但那只是我:-)@Nik-meh,我不太关心编译器的问题:)我同意Guillermo的答案更有效,因为它有更多的并行性-我只是按原样修复了原始代码-他对其进行了更大程度的修改。我今天整天都坐在电话会议上:DcDe<代码>等待
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;
}
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));
}
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));
}