-1
我一直在努力通過來自NHibernate網站的this article來實現UnitOfWork模式,並且遇到了一個我無法解決的問題。在第3節中,這是實現線程安全的地方,有一個測試引發了一個空引用異常。我沒有多線程的經驗,所以我不知道如何在這裏繼續。多線程測試中的空引用
你能告訴我問題是什麼嗎?
測試代碼
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);
}
代碼進行測試
public interface ILocalData
{
object this[object key] { get; set; }
int Count { get; }
void Clear();
}
public static class Local
{
static readonly ILocalData _data = new LocalData();
public static ILocalData Data
{
get { return _data; }
}
private class LocalData : ILocalData
{
[ThreadStatic]
private static Hashtable _localData = new Hashtable();
public object this[object key]
{
get { return _localData[key]; }
set { _localData[key] = value; }
}
public int Count
{
get { return _localData.Count; } <<<<<<< ######## EXCEPTION HERE #########
}
public void Clear()
{
_localData.Clear();
}
}
}
從技術上講,通過測試,但在輸出中,我可以看到,有一個空引用異常:
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; 私人靜態Hashtable的localData { 得到 { 如果(_localData == NULL) \t { \t \t _localData =新的Hashtable(); \t} return _localData; } }' – brainbolt
@brainbolt是的,這將工作。 –