首页 > 解决方案 > C# Parallel.ForEach,没有按预期工作

问题描述

在我的控制台应用程序中遇到一个奇怪的并行 Foreach 循环问题,我遍历一个实体集合,即轮询并调用一个 api 来获取 url,以及一个函数 getTemplateDiscription 来获取各种语言内容。问题是当我使用单线程运行它时,它可以正常工作,但是当我使用多线程运行时,没有为所有记录设置内容,即某些内容被设置为空。但是单线程工作正常。以下是代码片段:

//Global variable - Outside the Parallel Foreach. 
  //Guid contactId, templateIdEnglish, templateIdEnglishReminder, templateIdGerman, templateIdGermanReminder  
    Parallel.ForEach<acn_poll, OrganizationServiceProxy>(
        pollList,
        new ParallelOptions() { MaxDegreeOfParallelism = maxDegreeOfParallelism },
        () => { return CreateServiceProxy(); },
        (poll, loopstate, index, threadProxy) =>
        {
            //Logic to call api
            var content1 = getTemplateDescription(contactId, templateIdEnglish, threadProxy);
            var content2 = getTemplateDescription(contactId, templateIdEnglishReminder, threadProxy);
            var content3 = getTemplateDescription(contactId, templateIdGerman, threadProxy);
            var content3 = getTemplateDescription(contactId, templateIdGermanReminder, threadProxy);
            //update poll entity with Content
        }

我曾尝试在多线程模式下调试(即 maxDegreeOfParallelism > 1),但没有得到任何线索,因为由于多线程,代码正在运行是曲折形式。以下是未按预期返回输出的函数。在单线程中正确设置所有内容字段,但在多线程模式下,它以某种方式返回 null。

public static string getTemplateDescription(Guid contactId, Guid templateId, IOrganizationService service)
{        

        if (templateId == Guid.Empty)
            return "";

        string content = string.Empty;

    InstantiateTemplateRequest instTemplateReq = new InstantiateTemplateRequest
    {
        TemplateId = templateId,
        ObjectId = contactId,
        ObjectType = "Contact"
    };

    InstantiateTemplateResponse instTemplateResp = (InstantiateTemplateResponse)service.Execute(instTemplateReq);

    if (instTemplateResp != null)
    {
        Entity template = instTemplateResp.EntityCollection.Entities[0];
        if (template != null && template.Attributes.Contains("description"))
        {                       
            content = template.Attributes["description"].ToString();
        }
    }
    return content;
}

标签: c#parallel.foreach

解决方案


推荐阅读