我有一个名为HandleMessage
的方法,启动一个新线程来处理该消息。如果成功获取锁定对象,则处理它。否则将消息放入队列中。 SynchronizationLockException
始终会Monitor.Exit(o)
,因为await
上下文不再出现在原始帖子中。什么是正确的实施方式?
public void HandleMessage(string message)
{
Task.Factory.StartNew(async delegate
{
if (Monitor.TryEnter(o))
{
try
{
do
{
await HandleMessageAsync(message);
}
while (queue.TryDequeue(out message));
}
finally
{
Monitor.Exit(o);
}
}
else
{
queue.Enqueue(message);
}
});
}
答案 0 :(得分:4)
正如您所注意到的,Monitor.Enter / Exit是线程仿射的。
在他关于创建异步友好协调原语的系列文章中,Stephen包含一个AsyncLock,它应该是您正在寻找的AFAICT。
答案 1 :(得分:1)
现在我发现这里的同步锁object o
没用,因为我的queue
是并发的。最后解决方案是:
public void HandleMessage(string message)
{
Task.Factory.StartNew(async delegate
{
while (queue.TryDequeue(out message));
{
await HandleMessageAsync(message);
}
});
}
这解决了这个问题。但它本身并没有回答这个问题。