收集被修改;枚举操作可能不会执行错误?

时间:2016-01-27 14:05:17

标签: c# wpf

 public WorkflowQARuleSet GetQARule(int userNumber, int userNumberExternal, string applicationID,
         short computerNumber, long ruleBitID)
    {

        try
        {
            if (qaRules == null)
                qaRules = new List<WorkflowQARuleSet>();

            WorkflowQARuleSet wfQaRule = qaRules.FirstOrDefault(
                                                qaRule =>
                                                    qaRule != null &&
                                                    qaRule.QARuleBits63 != null &&
                                                    qaRule.QARuleBits63 == ruleBitID);

            if (wfQaRule == null)
            {
                WorkflowRuleSetApiClient workflowruleAPIClient = new WorkflowRuleSetApiClient(System.Configuration.ConfigurationManager.AppSettings["service:workflow_management_base_uri"]);

                wfQaRule = workflowruleAPIClient.GetQARuleSet(userNumber, userNumberExternal, applicationID, computerNumber, ruleBitID, WorkflowTypes.PaymentProcessing).FirstOrDefault();

            }




            if (wfQaRule != null)
                qaRules.Add(wfQaRule);

            if (wfQaRule != null && wfQaRule.QARuleBits63 == null)
                logger.Warn(string.Format("Invalid QA Rule Bits 63, {0}", wfQaRule.Name));

            return wfQaRule;


        }
        catch (Exception ex)
        {
            logger.Error("Error in getting QA rule set.", ex);
            throw ex;
        }

    }

这是我的整个代码和错误

  

System.InvalidOperationException:修改了集合;枚举操作可能无法执行。      在System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource资源)      在System.Collections.Generic.List 1.Enumerator.MoveNextRare() at System.Collections.Generic.List 1.Enumerator.MoveNext()      在System.Linq.Enumerable.FirstOrDefault [TSource](IEnumerable 1 source, Func 2谓词)      在Smi.Smart.PaymentProcessing.BusProcess.PaymentProcessingBP.GetQARule(Int32 userNumber,Int32 userNumberExternal,String applicationID,Int16 computerNumber,Int64 ruleBitID)

以上是我的代码和错误。任何人都可以验证这个吗?

2 个答案:

答案 0 :(得分:1)

GetQARuleSet或GetQARule方法可能有一个循环,在循环中它可能会添加或删除它正在循环的集合的成员。 这样做会改变集合和结束枚举。

从循环内部或从另一个线程修改集合是导致此异常的主要原因。

如果您希望将项目添加到集合中,您正在循环(或删除项目) 您可以存储要添加的项目和要在临时集合中删除的项目,然后在foreach()循环完成后添加或减去它们。

答案 1 :(得分:0)

从堆栈跟踪

  

在Smi.Smart.PaymentProcessing.BusProcess.PaymentProcessingBP.GetQARule(Int32 ......

的System.Linq.Enumerable.FirstOrDefault [TSource](IEnumerable1 source,Func2谓词)

您可以看到在quRules

枚举期间发生了异常
WorkflowQARuleSet wfQaRule = qaRules.FirstOrDefault(
                                            qaRule =>
                                                qaRule != null &&
                                                qaRule.QARuleBits63 != null &&
                                                qaRule.QARuleBits63 == ruleBitID);

我能想到如何在此处抛出InvalidOperationException的唯一方法是在quRules枚举时更改另一个线程中的枚举(FirstOrDefault)。

因此,找出哪个线程和哪个方法更改此集并执行某些同步。你可以尝试锁定:

WorkflowQARuleSet wfQaRule; 
lock(qaRules)
    wfQaRule = qaRules.FirstOrDefault(
                                            qaRule =>
                                                qaRule != null &&
                                                qaRule.QARuleBits63 != null &&
                                                qaRule.QARuleBits63 == ruleBitID);

请注意,您还需要lock其他帖子中的列表。