我已經上傳了一些代碼在git集線器,可以在這裏找到: https://github.com/Shaunus87/SyncTest其中包括我的原型代碼和我的單元測試它。單元測試同步代碼有競爭條件?
我基本上宣告我的同步碼,掛鉤事件,調用最終會調用事件的方法,並斷言該事件是否被稱爲與否:
bool called = false;
var testBinsToVend = GetRoboBins();
var vendHelper = new VendingHelper(null, testBinsToVend, VendType.Issue);
vendHelper.Complete += delegate() {
called = true;
};
vendHelper.DoVending();
Assert.IsTrue(called);
所有的代碼是同步的(如據我所知),但如果我運行測試失敗,如果我通過它進行調試,它會通過...
我已經嘗試了幾件事情,它似乎或者a)我的代碼是祕密異步和我有一個競爭條件或b)當運行代碼時,它決定不執行一半的事件?
到底是什麼?
編輯: 我也試着設置一個手動重置事件象下面這樣:
bool called = false;
var done = new ManualResetEvent(false);
var testBinsToVend = GetRoboBins();
var vendHelper = new VendingHelper(null, testBinsToVend, VendType.Issue);
vendHelper.Complete += delegate() {
called = true;
done.Set();
};
vendHelper.DoVending();
done.WaitOne();
Assert.IsTrue(called);
//was complete called?
Assert.AreEqual(true, vendHelper.Bins.All(x => x.State != VendState.Pending));
但因爲它是執行一條線,當done.WaitOne();
被擊中測試永遠不會到達Assert.IsTrue(called);
線。
我在那裏發現了對'System.Threading.Timer'的引用,你確定**你的代碼是同步的嗎?該事件從哪裏開始?在[Timer_Tick]裏面(https://github.com/Shaunus87/SyncTest/blob/master/eVendVendingMachines/BaseVendingMachine.cs#L182)?在這個'called = true;'行放置一個斷點並檢查調用堆棧,這可能會告訴你在調試過程中需要知道的一切。 –