简体   繁体   中英

Is it possible for a managed thread to have a Race Condition with itself

So in order to have a separate context for each thread that the program is running I set up a Context - Thread mapping class as follows

      public class ContextMap : IContextMap
{
    private static IContextMap _contextMap;
    private Dictionary<int, IArbContext2> ContextDict;
    private static string DbName;
    private ContextMap()
    {
        if (string.IsNullOrWhiteSpace(DbName))
            throw new InvalidOperationException("Setup must be called before accessing ContextMap");
        ContextDict = new Dictionary<int, IArbContext2>();
    }

    protected internal static void Setup(IContextMap map)
    {
        _contextMap = map;
    }

    public static void Setup(string dbName)
    {
        DbName = dbName;
    }

    public static IContextMap GetInstance()
    {
        return _contextMap ?? (_contextMap = new ContextMap());
    }


    public IArbContext2 GetOrCreateContext()
    {
        var threadId = Thread.CurrentThread.ManagedThreadId;
        if(!ContextDict.ContainsKey(threadId))
            ContextDict.Add(threadId,new ArbContext(DbName));
        return ContextDict[threadId];
    }

    public void DestroyContext()
    {
        if (ContextDict.ContainsKey(Thread.CurrentThread.ManagedThreadId))
            ContextDict.Remove(Thread.CurrentThread.ManagedThreadId);
    }

Somehow the code is (very rarely but still happening) throwing a keynotfound exception in the GetOrCreateContext method. Is it possible for a thread to be sidetracked to a separate action (eg the overseeing thread forces it to do another action that causes the thread to call DestroyContext after it checked if the Dict had the key but before it returned it) and then to resume where it left off. I never specifically do this but I can't understand any other reason how this error is being thrown.

Thank You.

The problem here is that Dictionary is not thread-safe. There can be unexpected behaviour when multiple threads try to access it, even if they are all using unique keys, because creating or removing a key/value pair is not an atomic action.

The easiest fix would be to use a ConcurrentDictionary in its place for ContextDict

Answering your literal question, NOT attempting to solve your problem. (@BenAaronsom has already done that.)

No: You have a "race condition" when the result of some computation depends on the order in which two or more threads access the same variable. If there is only one thread running in the race, then no matter how many times you run it, the same thread will always win. If a single-threaded program gives a non-deterministic answer, then whatever the problem is, it's not a race condition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM