如果收到預期數量的異步回呼,則應該測驗以下類:
class Program
{
static List<int> callbackObjects = new List<int>();
static int expectedNumberOfCallbacks;
static void Main(string[] args)
{
expectedNumberOfCallbacks = 10;
Monitor.Enter(callbackObjects);
CallbackTest.CallbackTester.TriggerCallbacks(expectedNumberOfCallbacks,Callback);
Monitor.Wait(callbackObjects,10000);
Assert.AreEqual(callbackObjects.Count, expectedNumberOfCallbacks);
}
private static void Callback(int callbackObject)
{
callbackObjects.Add(callbackObject);
Console.WriteLine($"Callback number {callbackObjects.Count}");
if(callbackObjects.Count == expectedNumberOfCallbacks)
{
Monitor.Exit(callbackObjects);
}
}
}
代碼輸出
Callback number 1
Callback number 2
Callback number 3
Callback number 4
Callback number 5
Callback number 6
Callback number 7
Callback number 8
Callback number 9
Callback number 10
但隨后它拋出了一個
System.Threading.SynchronizationLockException: 'Object synchronization method was called from an unsynchronized block
在執行
Monitor.Exit(callbackObjects);
是因為Monitor.Enter并且Monitor.Exit在不同的范圍/執行緒中被呼叫嗎?
我怎樣才能重寫代碼,做
Assert.AreEqual(callbackObjects.Count, expectedNumberOfCallbacks)
Main在收到預期數量的回呼或預定義的超時之后進行測驗?
uj5u.com熱心網友回復:
是因為
Monitor.Enter并且Monitor.Exit在不同的范圍/執行緒中被呼叫嗎?
是的,正是這樣。Monitor是執行緒系結的。
但是,IMO 您還應該考慮多個回呼本身是否可以重疊;如果是,則需要在回呼內部進行同步,以便callbackObjects.Add明確定義。可能你真正需要的是lock和Pulse:
static void Main(string[] args)
{
expectedNumberOfCallbacks = 10;
lock (callbackObjects)
{
CallbackTest.CallbackTester.TriggerCallbacks(
expectedNumberOfCallbacks,Callback);
Monitor.Wait(callbackObjects, 10000);
Assert.AreEqual(callbackObjects.Count, expectedNumberOfCallbacks);
}
}
private static void Callback(int callbackObject)
{
lock (callbackObjects)
{
callbackObjects.Add(callbackObject);
Console.WriteLine($"Callback number {callbackObjects.Count}");
if(callbackObjects.Count == expectedNumberOfCallbacks)
{
Monitor.Pulse(callbackObjects);
}
}
}
Wait釋放監視器并等待信號或超時重新獲取它;Pulse并將PulseAll該信號發送到等待執行緒(或執行緒)。
您還可以使用 from 的回傳值Wait來確定您是否收到信號(與超時相比)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/496623.html
