集合已修改;枚举操作可能不会执行错误

本文关键字:执行 错误 操作 修改 枚举 集合 | 更新日期: 2023-09-27 18:32:17

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

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

集合已修改;枚举操作可能不会执行错误

从堆栈跟踪

at

System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1 source, Func2 predicate) at Smi.Smart.PaymentProcessing.BusProcess.PaymentProcessingBP.GetQARule(Int32...

您可以看到在此枚举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列表。

GetQARuleSet

或 GetQARule 方法可能有一个循环,在循环中,它可能正在向其循环访问的集合添加或删除成员。这样做将更改集合和结束枚举。

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

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