【问题标题】:ConcurrentDictionary InvalidOperationException c#ConcurrentDictionary InvalidOperationException c#
【发布时间】:2015-10-24 07:45:33
【问题描述】:

这是错误:

System.InvalidOperationException:集合已修改;枚举操作可能无法执行。
在 System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource 资源)
在 System.Collections.Generic.List1.Enumerator.MoveNextRare()
at System.Collections.Generic.List
1.Enumerator.MoveNext()
在 System.Linq.Enumerable.WhereListIterator1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1 来源)
块引用

我使用静态 Dictionary for web api

这是我用于 Web api 的课程:

public class UsersSecureProvider
{
    public static ConcurrentDictionary<short, List<UserSecure>> _Users = new ConcurrentDictionary<short, List<UserSecure>>();

    public bool Add(short Group, UserSecure Message)
    {
        try
        {
            var GetList = GetByKey(Group);

            if (GetList != null)
            {
                GetList.Add(Message);
                return Update(Group, GetList, GetList);
            }
            else
            {
                GetList = new List<UserSecure>();
                GetList.Add(Message);
                return Add(Group, GetList);
            }
        }
        catch { }

        return false;
    }

    private bool Add(short key, List<UserSecure> SendUser)
    {
        return _Users.TryAdd(key, SendUser);
    }

    public bool Remove(short Key)
    {
        List<UserSecure> listremove;
        return _Users.TryRemove(Key, out listremove);
    }

    public List<UserSecure> GetByKey(short Group)
    {
        var listView = new List<UserSecure>();
        if (_Users != null)
        {
            var getList = _Users.TryGetValue(Group, out listView);
        }

        return listView;
    }

    public bool Update(short Group, List<UserSecure> oldlist, List<UserSecure> newlist)
    {
        return _Users.TryUpdate(Group, newlist, oldlist);
    }

    public void Clear()
    {
        _Users.Clear();
    }

    public ConcurrentDictionary<short, List<UserSecure>> GetAll()
    {
        return _Users;
    }

    public bool UpdateListByUser(short Group, List<UserSecure> newlist)
    {
        var OldList = GetByKey(Group);
        return _Users.TryUpdate(Group, newlist, OldList);
    }
}

我给班级打电话

 var _providers = new UsersSecureProvider();

        List<UserSecure> GetAll = _providers.GetByKey(1);

        if (GetAll != null && GetAll.Any() && GetAll.Where(w => w.UserID == UserID && w.Key == UniqueSecure).Count() > 0)
        {
            result = true;
        }
        else
        {
                _providers.Add(1, new UserSecure { UserID = UserID, Key = UniqueSecure });
        }

为什么我会收到这个错误异常?

谢谢。

【问题讨论】:

  • 哪一种方法导致了异常?
  • 你在哪里调用Count()函数?
  • 当您在迭代中添加/删除项目时,通常会发生此错误。这可以通过迭代集合来解决,而不是迭代集合的副本。喜欢:_Users.ToArray()
  • @JeroenvanLangen,问题不在提供 OP 的代码中,而是在某些外部:在某些集合中使用 Count() 的地方,我不确定字典的问题
  • @Ori,你在哪里调用函数Where(...).Count()?

标签: c# asp.net asp.net-mvc list asp.net-web-api


【解决方案1】:

这个:

List<UserSecure> GetAll = _providers.GetByKey(1);

返回对基础集合的引用。对可能通过您拥有的其他 WebAPI 操作之一修改的列表的相同引用。你不能同时枚举和修改List&lt;T&gt;

相反,创建一个新的List&lt;T&gt; 并枚举它:

List<UserSecure> GetAll = _providers.GetByKey(1).ToList();

【讨论】:

  • 在这种情况下 - 不起作用else 分支尝试将元素添加到列表
  • @Grundy 他只是在列举它。他在修改字典,而不是列表。
  • 感谢您的帮助。但为什么要 ToList()?已经上榜了
  • @YuvalItzchakov,你说得对! providers 与 gettted 列表混淆。
  • @Ori 因为不能同时枚举和修改同一个列表
【解决方案2】:

如果您的应用程序是多线程的,则建议使用信号量。例如

private static object _sync = new object();
public List<UserSecure> GetByKey(short Group)
{
    lock(_sync)
    {
        var listView = new List<UserSecure>();
        if (_Users != null)
        {
            var getList = _Users.TryGetValue(Group, out listView);
        }

        return listView;
    }
}

【讨论】:

  • ConcurrentDictionary 已经在里面使用了类似的东西。还有您的示例如何帮助解决wherecount 函数中的问题OP?
  • 首先你的代码中哪一行会崩溃?
  • 向 OP 询问这个:-D
  • 在这种情况下,我会将信号量用于所有方法,仅用于测试。如果这项工作我会用其他东西替换ConcurrentDictionary,也许是普通的Dictinonary
  • 但是如果已经实现了,为什么还需要手动执行呢? :-) 如果您查看错误-您可以看到所有在WhereIterator 上调用的Count 函数都发生了,该函数返回Where 函数,在某些List&lt;T&gt; 上调用。在提供 OP 的代码中 - 您看不到任何此功能。所以问题不在ConcurrentDictionary
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
相关资源
最近更新 更多