首页 > 解决方案 > foreach 中的异步方法并将结果添加到列表中

问题描述

我想在 foreach 中运行几种异步方法。返回值应写入列表。

该方法在 WPF 应用程序中执行。该方法GetItemPricesFromJsonAsync从网络数据中获取。

public async Task LoadBlackMarketListView(List<MarketAnalysisManager.ItemTier> tiers, List<MarketAnalysisManager.ItemLevel> levels, 
            List<MarketAnalysisManager.ItemQuality> quialityList, string outdatedHours, string profit, Location? location)
        {
            await Task.Run(async () =>
            {
                var blackMarketSellObjectList = new List<BlackMarketSellObject>();

                var items = await MarketAnalysisManager.GetItemListAsync(tiers, levels);

                await Dispatcher.InvokeAsync(() =>
                {
                    PbBlackMarketMode.Minimum = 0;
                    PbBlackMarketMode.Maximum = items.Count;
                    PbBlackMarketMode.Value = 0;
                    GridBlackMarketMode.IsEnabled = false;
                    LvBlackMarket.Visibility = Visibility.Hidden;
                    PbBlackMarketMode.Visibility = Visibility.Visible;
                });

                foreach (var item in items)
                {
                    var allItemPrices = await MarketAnalysisManager.GetItemPricesFromJsonAsync(item.UniqueName, true);
                    if (allItemPrices.FindAll(a => a.City == Locations.GetName(Location.BlackMarket)).Count <= 0)
                    {
                        await IncreaseBlackMarketProgressBar();
                        continue;
                    }

                    blackMarketSellObjectList.AddRange(await GetBlackMarketSellObjectList(item, quialityList, allItemPrices, outdatedHours, profit, location));

                    await IncreaseBlackMarketProgressBar();
                }

                await Dispatcher.InvokeAsync(() =>
                {
                    LvBlackMarket.ItemsSource = blackMarketSellObjectList;
                    PbBlackMarketMode.Visibility = Visibility.Hidden;
                    LvBlackMarket.Visibility = Visibility.Visible;
                    GridBlackMarketMode.IsEnabled = true;
                });
            });

        }

目前看来,他一次只做一件事。

运行... 0

结束... 0

运行... 1

结束... 1

运行... 2

结束... 2

标签: c#wpfforeachasync-await

解决方案


您将需要存储任务,而不是等待它们。然后,您可以等待所有这些。
试试这个(用我的代码替换你的 foreach)。
我还建议您使用真实方法而不是匿名方法,它更具可读性。

List<Task> tasks = new List<Task>();
foreach (var item in items)
{
    tasks.Add(Task.Run(async () => 
    {
        var allItemPrices = await MarketAnalysisManager.GetItemPricesFromJsonAsync(item.UniqueName, true);
        if (allItemPrices.FindAll(a => a.City == Locations.GetName(Location.BlackMarket)).Count <= 0)
        {
            await IncreaseBlackMarketProgressBar();
            return;
        }

        blackMarketSellObjectList.AddRange(await GetBlackMarketSellObjectList(item, quialityList, allItemPrices, outdatedHours, profit, location));

        await IncreaseBlackMarketProgressBar();
    }));
}

await Task.WhenAll(tasks);

注意:现在有一个 return 而不是 continue 因为这是一个匿名函数,你只需要在那里结束函数而不是继续 foreach。


推荐阅读