【问题标题】:Async method with Parallel.ForEach [duplicate]带有 Parallel.ForEach 的异步方法 [重复]
【发布时间】:2022-02-14 22:16:12
【问题描述】:

我对异步方法没有太多经验,我不确定我是否正确地使用了每个方法。在某些情况下,我在以下行中获取索引超出范围异常:“listPages.Add”

private static int SetPages(FileDocument document, List<PageDTO> pages, string tableName, Entities entity, int accessID)
{
   List<Page> listPages = new List<Page>();
            
    Parallel.ForEach(pages, new ParallelOptions { MaxDegreeOfParallelism = 8 }, page =>
    {
        string docPath = GetPathString(page.PageID);
        if (File.Exists(docPath))
        {
            byte [] docBytes = ConvertToWebP(docPath);
            if(docBytes.Length > 0)
            {
                var fileStreamID = InsertInDatabase(docBytes, page.PageID, tableName);
                listPages.Add(SetPage(document, page.PageNumber, fileStreamID, tableName, accessID));
            }
        }
    });
            
    entity.FilePages.AddRange(listPages);
    return listPages.Count();
}

【问题讨论】:

  • 您的代码不是线程安全的。您不应该在 Parallel.ForEach 正文中使用共享的可变集合。
  • 你的方法不是异步的,它是静态的
  • “使用 Parallel.ForEach 的异步方法” - 不,只是不。不。 ;D
  • Parallel 专为 CPU 绑定操作而设计,因此请勿用于 I/O 绑定异步操作。

标签: c#


【解决方案1】:

因为您的代码可能满足竞速条件,所以有很多线程操作 List&lt;Page&gt; listPages = new List&lt;Page&gt;()List&lt;&gt; 不是线程安全的集合

我会使用ConcurrentBag<> 而不是List&lt;&gt;,因为ConcurrentBag&lt;&gt; 是一个线程安全的集合。

表示线程安全、无序的对象集合。

private static int SetPages(FileDocument document, List<PageDTO> pages, string tableName, Entities entity, int accessID)
{
    ConcurrentBag<Page> listPages = new ConcurrentBag<Page>()
    Parallel.ForEach(pages, new ParallelOptions { MaxDegreeOfParallelism = 8 }, page =>
    {
        string docPath = GetPathString(page.PageID);
        if (File.Exists(docPath))
        {
            byte [] docBytes = ConvertToWebP(docPath);
            if(docBytes.Length > 0)
            {
                var fileStreamID = InsertInDatabase(docBytes, page.PageID, tableName);
                listPages.Add(SetPage(document, page.PageNumber, fileStreamID, tableName, accessID));
            }
        }
    });
            
    entity.FilePages.AddRange(listPages.ToList());
    return listPages.Count();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多