加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 获取集合已被修改;枚举操作可能无法执行.例外

发布时间:2020-12-15 17:48:26 所属栏目:百科 来源:网络整理
导读:收集被修改;枚举操作可能无法执行.例外 码: public static string GetValue(ListStateBag stateBagList,string name){ string retValue = string.Empty; if (stateBagList != null) { foreach (StateBag stateBag in stateBagList) { if (stateBag.Name.Equ
收集被修改;枚举操作可能无法执行.例外

码:

public static string GetValue(List<StateBag> stateBagList,string name)
{
    string retValue = string.Empty;

    if (stateBagList != null)
    {
        foreach (StateBag stateBag in stateBagList)
        {
            if (stateBag.Name.Equals(name,StringComparison.InvariantCultureIgnoreCase))
            {
                retValue = stateBag.Value;
            }
        }
    }

    return retValue;
}

在某个时间点获得此异常并非每次都在这个地方.

堆栈跟踪:

at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource
resource)

at System.Collections.Generic.List`1.Enumerator.MoveNextRare()

at System.Collections.Generic.List`1.Enumerator.MoveNext()

at Tavisca.TravelNxt.Shared.Entities.StateBag.GetValue(List`1 stateBagList,String name)

@no我试过以下代码,但仍然有异常

码:

class StateBag
{
    public string Name;
    public string Value;
}

class Program
{
    static List<StateBag> _concurrent = new List<StateBag>();

    static void Main()
    {
        var sw = new Stopwatch();
        try
        {
            sw.Start();
            Thread thread1 = new Thread(new ThreadStart(A));
            Thread thread2 = new Thread(new ThreadStart(B));
            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();
            sw.Stop();
        }
        catch (Exception ex)
        {
        }


        Console.WriteLine("Average: {0}",sw.ElapsedTicks);
        Console.ReadKey();
    }

    private static Object thisLock = new Object();

    public static string GetValue(List<StateBag> stateBagList,string name)
    {
        string retValue = string.Empty;


        if (stateBagList != null)
        {
            lock (thisLock)
            {
                foreach (StateBag stateBag in stateBagList)
                {
                    if (stateBag.Name.Equals(name,StringComparison.InvariantCultureIgnoreCase))
                    {
                        retValue = stateBag.Value;
                    }
                }
            }

        }



        return retValue;
    }

    static void A()
    {
        for (int i = 0; i < 5000; i++)
        {
            _concurrent.Add(new StateBag() { Name = "name" + i,Value = i.ToString() });
        }
    }

    static void B()
    {
        for (int i = 0; i < 5000; i++)
        {
            var t = GetValue(_concurrent,"name" + i);
        }
    }
}

解决方法

Getting Collection was modified; enumeration operation may not execute. exception

原因:当您循环的枚举在同一个线程或其他某个线程中被修改时,会发生此异常.

现在,在您提供的代码中,没有任何此类方案.这意味着您可能在多线程环境中调用它,并且在其他一些线程中修改了集合.

解决方案:在枚举上实现锁定,以便一次只能访问一个线程.这样的事情应该做到这一点.

private static Object thisLock = new Object();
public static string GetValue(List<StateBag> stateBagList,string name)
{
    string retValue = string.Empty;

    if (stateBagList != null)
    {
        lock(thisLock)
        {
            foreach (StateBag stateBag in stateBagList)
            {
               if (stateBag.Name.Equals(name,StringComparison.InvariantCultureIgnoreCase))
               {
                retValue = stateBag.Value;
                }
             }
        }
    }

    return retValue;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读