Parallel.ForEachAsync 需要帮助

Parallel.ForEachAsync help needed

好的。所以我首先要先道歉,因为我知道有很多关于 Parallel 和 Async 的问题。然而,即使在搜索之后,我也无法全神贯注于它应该如何工作。编码是我涉猎的事情,而不是我日复一日做的事情。

我正在尝试帮助一位朋友使用 AlphaVantage 收集一些历史股票数据 API。

我收集数据并将其保存到数据库没有问题,但提取 20 年的每日价格可能需要很长时间。因此,为了避免 GUI 冻结,我将其设为异步函数。但是,考虑到需要提取的数据频率和数量,需要并行完成。我不确定有多少并行事件,但长期目标是在应用程序中有一个计时器,它每隔一段时间触发并调用 BatchUpdateStockHistoryAsync 方法并传入一个值,用于提取和更新多少股票这批功能然后将出去,查询数据库并获得最旧更新的列表 5。

目前,我将所有这些都剥离为简单的问题,并创建了一个包含 5 只股票的手动列表,这些股票会被迭代。对于列表中的每只股票,它都会调用另一个函数 PullAndWriteHistoricDailyData(item),该函数完成实际联系 AlphaVantage 和更新数据库的所有工作。

看完这些冗长的信息后,我的问题是触发 PullAndWriteHistoricDailyData() 的多个并发线程的最佳方法是什么?

我想我还需要使用 MaxDegreeOfParallelism 来找出最有效的方法,但我什至还没有做到这一点。我相信我可能想使用 Parallel.ForEachAsync?但不确定如何将它们整合在一起。

如有任何帮助,我们将不胜感激

米修

    public async Task BatchUpdateStockHistoryAsync()
    {
        List<string> list = new List<string>();

        list.Add("AAPL");
        list.Add("F");
        list.Add("MSFT");
        list.Add("COKE");
        list.Add("IAG");

        foreach(string item in list)
        {
            await Task.Run(() => PullAndWriteHistoricDailyData(item));
        }

        return completed;
    }

EDIT 我最初错误地阅读了 Task.WhenAllParallel.ForEach。在根据 Theodore Zoulias 在 is-parallel-foreachasync-a-replacement-to-a-plain-for-loop-append-to-task-list 的回答阅读了有关 Parallel.ForEachAsync 的更多信息后,并基于您希望查看每个任务的结果而不是从调用接收单个任务的假设Parallel.ForEachAsync,那么我建议改为使用以下内容:

您可以切换到使用 List<Task> 并使用 await Task.WhenAll() 并跳过 Parallel.ForEachAsync,如下所示:

 List<Task> myupdatetasks = new List<Task>();

 foreach(string item in list)
 {
     myupdatetasks.Add(Task.Run(() => PullAndWriteHistoricDailyData(item)));
 }

 await Task.WhenAll(myupdatetasks).ConfigureAwait(false);

如果 PullAndWriteHistoricDailyData() 已经是一个 async 方法,你不需要使用 Task.Run,你可以像上面一样做减去 Task.Run

 List<Task> myupdatetasks = new List<Task>();

 foreach(string item in list)
 {
     myupdatetasks.Add(PullAndWriteHistoricDailyData(item));
 }

 await Task.WhenAll(myupdatetasks).ConfigureAwait(false);

如果您打算使用 Parallel.ForEachAsync,这篇文章解释得很好:parallelforeachasync-in-net-6