C# 多线程测试中的空引用
我一直在通过NHibernate网站来实现UnitOfWork模式,但我遇到了一个无法解决的问题。在第3节中,实现是线程安全的,有一个测试抛出空引用异常。我没有多线程方面的经验,所以我不知道如何在这里继续 你能告诉我是什么问题吗 测试代码C# 多线程测试中的空引用,c#,multithreading,C#,Multithreading,我一直在通过NHibernate网站来实现UnitOfWork模式,但我遇到了一个无法解决的问题。在第3节中,实现是线程安全的,有一个测试抛出空引用异常。我没有多线程方面的经验,所以我不知道如何在这里继续 你能告诉我是什么问题吗 测试代码 private ManualResetEvent _event; [Test] public void Local_data_is_thread_local() { Console.WriteLine("Starting in main thread
private ManualResetEvent _event;
[Test]
public void Local_data_is_thread_local()
{
Console.WriteLine("Starting in main thread {0}", Thread.CurrentThread.ManagedThreadId);
Local.Data["one"] = "This is a string";
Assert.AreEqual(1, Local.Data.Count);
_event = new ManualResetEvent(false);
var backgroundThread = new Thread(RunInOtherThread);
backgroundThread.Start();
// give the background thread some time to do its job
Thread.Sleep(100); <<<<<<< ######## EXCEPTION AFTER THIS LINE #########
// we still have only one entry (in this thread)
Assert.AreEqual(1, Local.Data.Count);
Console.WriteLine("Signaling background thread from main thread {0}", Thread.CurrentThread.ManagedThreadId);
_event.Set();
backgroundThread.Join();
}
private void RunInOtherThread()
{
Console.WriteLine("Starting (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
// initially the local data must be empty for this NEW thread!
Assert.AreEqual(0, Local.Data.Count);
Local.Data["one"] = "This is another string";
Assert.AreEqual(1, Local.Data.Count);
Console.WriteLine("Waiting on (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
_event.WaitOne();
Console.WriteLine("Ending (background-) thread {0}", Thread.CurrentThread.ManagedThreadId);
}
问题在于:
[ThreadStatic]
private static Hashtable _localData = new Hashtable();
指示每个线程的\u localData
字段的值是唯一的。但是,初始化只在类型构造函数中执行一次,因此只有在其上执行类型构造函数的线程具有非null的\u localData
。所有其他线程都将具有null
从上面链接的MSDN站点:
不要为标记有ThreadStaticAttribute的字段指定初始值,因为此类初始化仅在类构造函数执行时发生一次,因此只影响一个线程。如果未指定初始值,则如果字段是值类型,则可以将其初始化为默认值;如果字段是引用类型,则可以将其初始化为null
我懂了。谢谢所以改为这样做:
[ThreadStatic]私有静态哈希表\u localData;私有静态哈希表localData{get{if(_localData==null){u localData=new Hashtable();}返回_localData;}}
@brainbolt是的,那会有用的。
Run started: C:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHinbernateUnitOfWork.Testing\bin\Debug\NHinbernateUnitOfWork.Testing.dll
Starting in main thread 18
Starting (background-) thread 19
System.NullReferenceException: Object reference not set to an instance of an object.
at NHibernateUnitOfWork.NHibernateUnitOfWork.Local.LocalData.get_Count() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHibernateUnitOfWork\Local.cs:line 37
at NHinbernateUnitOfWork.Testing.LocalData_Fixture.RunInOtherThread() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHinbernateUnitOfWork.Testing\LocalData_Fixture.cs:line 73
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
at NHibernateUnitOfWork.NHibernateUnitOfWork.Local.LocalData.get_Count() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHibernateUnitOfWork\Local.cs:line 37
at NHinbernateUnitOfWork.Testing.LocalData_Fixture.RunInOtherThread() in c:\Users\brainbolt\Documents\GitHub\NHibernateUnitOfWork\NHinbernateUnitOfWork.Testing\LocalData_Fixture.cs:line 73
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Signaling background thread from main thread 18
NUnit VS Adapter 2.0.0.0 executing tests is finished
[ThreadStatic]
private static Hashtable _localData = new Hashtable();