Ori Ben David
Ori Ben David

Reputation: 21

ConcurrentDictionary InvalidOperationException c#

this is the error:

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.List1.Enumerator.MoveNextRare()
at System.Collections.Generic.List
1.Enumerator.MoveNext()
at System.Linq.Enumerable.WhereListIterator1.MoveNext()
at System.Linq.Enumerable.Count[TSource](IEnumerable
1 source)
Blockquote

I use the static Dictionary for web api

this is my class that i use for my 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);
    }
}

And I call the class

 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 });
        }

why do i receive this error exception?

thank you.

Upvotes: 2

Views: 961

Answers (2)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149598

This:

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

Returns a reference to the underlying collection. That same reference to a list which is probably being modified via one of the other WebAPI actions you have. You cannot both enumerate and modify the List<T>.

Instead, create a new List<T> and enumerate it:

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

Upvotes: 3

roroinpho21
roroinpho21

Reputation: 742

If your application is multi threading it is recomanded to use semaphore. For example

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;
    }
}

Upvotes: -1

Related Questions