等待多个异步调用完成?
Posted
技术标签:
【中文标题】等待多个异步调用完成?【英文标题】:Waiting for multiple async calls to complete? 【发布时间】:2015-10-15 13:25:35 【问题描述】:我必须从 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();
任何建议都将不胜感激,因为我现在不知道该怎么做。
谢谢大家。
【问题讨论】:
异步调用的方法签名是什么?另外,您说:但它现在仍在等待所有调用完成,然后再继续执行下一段代码,这不正是您想要的吗? 那是一个错字 - 很抱歉。我的意思是说在继续下一段代码之前“不”等待所有调用完成。在查看生成的调用时,它们都设置为无效。 (希望我能正确理解您的问题) 我假设异步方法的方法签名是void
返回?
说清楚 - 这是c#,对吧?如果是这样,请添加标签。如果不是,请添加一个不同的标签。它看起来像 C#,但很可能是其他语言,可能有非常不同的异步和等待概念。
【参考方案1】:
来自 WCF 服务
我建议您重建 WCF 客户端代理,启用异步调用。目前,它使用的是an older pattern,但如果您使用现代Visual Studio 版本重新生成它,它应该会生成一个newer pattern,它与async
/await
配合使用效果更好。
那么您实际上可以在 WCF 调用中直接使用 await
:
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.Run
或Task.Wait
:
await CreateMultipleTasksAsync();
// At this point, the results have been retrieved and processed.
【讨论】:
Stephen Clearly - 非常感谢您的详细回复。我一直在使用 SvcUtil 来生成代理。因此,我删除了生成的文件,并直接通过 VS 将服务引用添加到我的项目中,但我得到“无法将类型 'void' 隐式转换为 'System.Threading.Tasks.Task'。这是在 Visual Studio 2013 中工作的一个 Xamarin PCL 应用程序。我只是创建代理完全错误吗? @SUCODev:我怀疑是 Xamarin 应用程序把它扔掉了。尝试创建常规 PCL 或 .NET 4.5 dll 并在其上生成服务引用。 嗨@StephenCleary。您的解决方案似乎正是我正在寻找的,但我不确定如何注册和连接 OnGotEventResult / OnGotLocationsResult / OnGotTypesResult。你愿意在你的答案中添加这个吗? @user919426:我的回答使用了 TAP (async
/await
) 方法,所以它根本不使用这些事件。以上是关于等待多个异步调用完成?的主要内容,如果未能解决你的问题,请参考以下文章