“对象同步方法是从非同步的代码块中调用的”回调测试错误
如果收到了预期数量的异步回调,则应该测试以下类:
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.enter.enter
和monitor.exit 在不同的范围/线程中调用?
如何重写代码,
Assert.AreEqual(callbackObjects.Count, expectedNumberOfCallbacks)
在收到预期的回调数或预定义超时之后,在main
中进行测试?
The following class is supposed to test, if an expected number of asynchronous Callbacks was received:
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(quot;Callback number {callbackObjects.Count}");
if(callbackObjects.Count == expectedNumberOfCallbacks)
{
Monitor.Exit(callbackObjects);
}
}
}
The code outputs
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
but then it throws an
System.Threading.SynchronizationLockException: 'Object synchronization method was called from an unsynchronized block
on executing
Monitor.Exit(callbackObjects);
Is it because Monitor.Enter
and Monitor.Exit
are invoked in different scopes/threads?
How can I rewrite the code, to do the
Assert.AreEqual(callbackObjects.Count, expectedNumberOfCallbacks)
test in Main
, either after the expected number of callbacks was received or a predefined timeout?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,正是那样。
Monitor
是线程的。但是,IMO您还应该考虑是否可以重叠多个回调;如果是,则需要在回调内同步,以便
callbackobjects.add
定义很好。您的真正需要的是lock
pulse :等待
发布监视器和等待信号或超时重新启动它;pulse
和pulseall
是将该信号发送到等待线程(或线程)的原因。您还可以使用
等待
的返回值来确定是否发出信号(vs timeout)。Yes, exactly that.
Monitor
is thread-bound.However, IMO you should also consider whether the multiple callbacks can themselves be overlapped; if they are, you need to synchronize inside the callback so that
callbackObjects.Add
is well-defined. It could be that what you really need here islock
andPulse
:Wait
releases a monitor and waits for either a signal or a timeout to re-acquire it;Pulse
andPulseAll
are what sends that signal to a waiting thread (or threads).You can also use the return value from
Wait
to determine whether or not you got signaled (vs timeout).