因此,为了为程序运行的每个线程提供单独的上下文,我设置了一个Context-Thread映射类,如下所示
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);
}
不知何故,代码(很少但仍然发生)在GetOrCreateContext方法中抛出一个keynotfound异常。是否有可能将线程转移到单独的操作(例如,监督线程强制它执行另一个操作,导致线程在检查Dict是否有密钥但在它返回之前调用DestroyContext)然后恢复它停止了。我从来没有专门这样做,但我无法理解如何抛出这个错误。
谢谢。
答案 0 :(得分:3)
这里的问题是Dictionary
不是线程安全的。当多个线程尝试访问它时可能会出现意外行为,即使它们都使用唯一键,因为创建或删除键/值对不是原子操作。
最简单的解决方法是在ConcurrentDictionary
ContextDict
答案 1 :(得分:0)
回答您的文字问题, NOT 尝试解决您的问题。 (@BenAaronsom已经做到了。)
否:你有一个&#34;竞争条件&#34;当某些计算的结果取决于两个或多个线程访问同一变量的顺序时。如果在竞赛中只有一个线程运行,那么无论你运行多少次,同一个线程总是会赢。如果单线程程序给出了非确定性的答案,那么无论问题是什么,它都不是竞争条件。