等待后的SynchronizationLockException

时间:2012-10-08 03:25:04

标签: c# multithreading windows-8 async-await

我有一个名为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);
            }
        });
    }

2 个答案:

答案 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);
        }
    });
}

这解决了这个问题。但它本身并没有回答这个问题。