c# - 如何正确使用 Task.WhenAll()

标签 c# .net asynchronous .net-4.5 async-await

我正在尝试使用 Task.WhenAll 来等待多个任务的完成。

我的代码如下 - 它应该启动多个异步任务,每个任务检索一条公共(public)汽车路线,然后将它们添加到本地数组。但是,Task.WhenAll(...) 立即返回,本地路由数组的计数为零。这看起来很奇怪,因为我希望每个 Task 中的各种 await 语句表示流程已暂停,并且 Task 不会返回直到完成。

List<Task> monitoredTasks = new List<Task>();
foreach (BusRouteIdentifier bri in stop.services)
{
    BusRouteRequest req = new BusRouteRequest(bri.id);

    // Start a new task to fetch the route for each stop
    Task getRouteTask = Task.Factory.StartNew(async () =>
    {
        var route = await BusDataProviderManager.DataProvider.DataBroker.getRoute(req);

            // Add the route to our array (on UI thread as it's observed)
            await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, delegate
            {
                this.routes.Add(route);
            });
    });

    // Store the task in our monitoring list
    monitoredTasks .Add(getRouteTask);
}

Debug.WriteLine("Awaiting WHENALL");
await Task.WhenAll(monitoredTasks );
Debug.WriteLine(string.Format("WHENALL returned (routes count is {0} ", this.routes.Count));

this.OnWillEndFetchingRoutes(new EventArgs());

我显然做错了什么 - 但是什么?

最佳答案

这归结于对 async-await 的真正工作原理缺乏基本的了解。

内部任务正在将流程返回到外部任务,然后在等待返回之前完成。

为了实现我想要的,我需要重构如下:

List<Task<BusRoute>> routeRetrievalTasks = new List<Task<BusRoute>>();
foreach (BusRouteIdentifier bri in stop.services)
{
    BusRouteRequest req = new BusRouteRequest(bri.id);
    routeRetrievalTasks.Add(BusDataProviderManager.DataProvider.DataBroker.getRoute(req));
}

foreach (var task in routeRetrievalTasks)
{
    var route = await task;
    this.routes.Add(route); // triggers events
}

感谢Dave Smits

关于c# - 如何正确使用 Task.WhenAll(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11950329/

相关文章:

c# - 如何使用jQuery调用c# webservice获取返回值

javascript - 如何在变量中获取 ClientID

java - 这两种方法一起是一种递归形式吗?

c# - 显示/隐藏 Mahapps 弹出控件

c# - 谁有我可以看到的异步网络请求的简单实现?

asp.net - 无法配置IIS/Asp.NET来同时处理许多异步请求

c# - 在单独的行上动态创建标签

c# - asp.net 网站 - 我可以判断它是否已预编译吗?

c# - 如何从字符串中删除\t char

javascript - 如何使用异步 I/O 将实时数据集写入磁盘?