0

I am facing an issue in Arithmetic overflow, I have posted the detail in this question [Dictionary to ToList ArithmeticFlowException

however I have found the reason, when I call the method

Global.SereverConnections.TryGetValue(key, out connections);

it throws overflow exception, having count of connections is equal to -1.

public static  IDictionary<string, ISet<ConnectionManager>> SereverConnections = new ConcurrentDictionary<string, ISet<ConnectionManager>>();

public static IList<ConnectionManager> GetUserConnections(string username)
{
    //Key must not be null in any case return null if someone send and empty username
    if (string.IsNullOrEmpty(username))
        return null;
    ISet<ConnectionManager> connections;

    Global.SereverConnections.TryGetValue(username, out connections);
    //this will make the copy of the 
    //return (connections != null ? connections.ToList() ?? Enumerable.Empty<ConnectionManager>().ToList() : null);

     //exception occurs in below line, and connections.Count==-1
    return (connections != null ? connections.ToList() : null); 
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
bilal
  • 648
  • 8
  • 26
  • There's nothing in your code that suggests how this happens. Wild guess: `Global.SereverConnections` is accessed from multiple threads, causing the dictionary to end up with an inconsistent state. – Jeroen Mostert Aug 21 '17 at 11:01
  • Can you share when the count of object is equal to -1 in dictionary. what is the behavior ? – bilal Aug 21 '17 at 11:01
  • Yes am using this in multithreaded environment, am doing load test @JeroenMostert – bilal Aug 21 '17 at 11:01
  • @JeroenMostert I have declared it ConcurrentDictionary, still I need locking mechanism for it? – bilal Aug 21 '17 at 11:06
  • No, because `ConcurrentDictionary.TryGetValue` is thread-safe. But `connections.ToList` is not. (Nor is enumeration ever a thread-safe operation, no matter what collection you use -- there is no `.ToList()` that will let you avoid locking.) – Jeroen Mostert Aug 21 '17 at 11:08

1 Answers1

1

Global.SereverConnections is a ConcurrentDictionary, and thus is thread-safe. But you are adding HashSets to it - and they are not thread-safe.

You can't call HashSet.ToList() at the same time as someone is adding items to it.

You will need to use locking around all accesses to the HashSet to ensure that you don't have threading issues. Or switch to using ConcurrentDictionary instead of HashSet (as per https://stackoverflow.com/questions/18922985/concurrent-hashsett-in-net-framework).

mjwills
  • 23,389
  • 6
  • 40
  • 63