等待多个异步调用完成?

问题描述:

我必须从WCF服务中调用三种不同的异步方法。我有以下方法,其中包括所有三个调用:等待多个异步调用完成?

private async Task CreateMultipleTasksAsync() 
{ 
    CrimcaseServiceClient client = new CrimcaseServiceClient(
     new BasicHttpBinding(), 
     new EndpointAddress("http://192.168.1.100/FooService/FooService.svc") 
     ); 

    client.GetEventCompleted += OnGotEventResult; 
    client.GetEventAsync(eventInfo); 

    client.GetLocationsCompleted += OnGotLocationsResult; 
    client.GetLocationsAsync(); 

    client.GetTypesCompleted += OnGotTypesResult; 
    client.GetTypesAsync(); 
} 

在所有三个调用完成后,我需要填充一些值。但是,我似乎遇到了如何等待所有三人首先完成的问题。

我已经试过这样做,使用这种电话,但它仍然不是等待所有的呼叫才去到下一个代码位来完成:

private void GrabData() 
{ 
    var task = Task.Run(async() => { await CreateMultipleTasksAsync(); }); 
    task.Wait(); 
} 

任何建议将不胜赞赏,因为我迷失在这个时候做什么。

谢谢大家。

+1

什么是你异步调用的方法签名?另外,你说:*但它仍然在等待所有的调用完成,然后再进入下一个代码*不是你想要的吗? –

+0

这是一个错字 - 对不起。我的意思是说,在进入下一个代码之前,它不是等待所有的调用完成。在查看生成的呼叫时,它们都被设置为无效。 (我希望我正确理解你的问题) – BrewingDev

+0

我假设方法签名是为异步方法是'无效'返回? –

从WCF服务

我建议你重建你的WCF客户端代理,并启用异步调用。目前,它使用的是an older pattern,但如果使用现代Visual Studio版本进行重新生成,则应生成newer pattern,与async/await的效果更好。

然后你就可以实际使用await与WCF直接调用:

private async Task CreateMultipleTasksAsync() 
{ 
    CrimcaseServiceClient client = new CrimcaseServiceClient(
    new BasicHttpBinding(), 
    new EndpointAddress("http://192.168.1.100/FooService/FooService.svc") 
    ); 

    // Start the three asynchronous calls. 
    var getEventTask = client.GetEventAsync(eventInfo); 
    var getLocationsTask = client.GetLocationsAsync(); 
    var getTypesTask = client.GetTypesAsync(); 

    // Asynchronously wait (await) for them all to complete. 
    await Task.WhenAll(getEventTask, getLocationsTask, getTypesTask); 

    // Retrieve the results of the calls. 
    var event = await getEventTask; 
    var locations = await getLocationsTask; 
    var types = await getTypesTask; 

    // TODO: place OnGotEventResult/OnGotLocationsResult/OnGotTypesResult logic here 
} 

你打电话时,你应该只是一个await这样做,不使用Task.RunTask.Wait

await CreateMultipleTasksAsync(); 
// At this point, the results have been retrieved and processed. 
+0

Stephen Clearly - 非常感谢你的细节回复。我一直在使用SvcUtil来生成代理。所以,我删除了生成的文件,并直接通过VS将服务引用添加到我的项目中,但是我得到了“无法将类型'void'隐式转换为'System.Threading.Tasks.Task'。一个Xamarin PCL应用程序,我只是创建代理完全错误? – BrewingDev

+1

@SUCODev:我怀疑这是Xamarin应用程序抛出它。尝试创建一个普通的PCL或.NET 4.5 dll并生成服务引用。 –