Search code examples
c#multithreadingwindows-8async-await

SynchronizationLockException after await


I have a method called HandleMessage, a new thread is started to handle the message. If the lock object is fetched successfully, then handle it. Otherwise put the message in the queue. A SynchronizationLockException is always thrown at Monitor.Exit(o) since after await the context isn't in the original thread any more. What's the correct way to implement?

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

Solution

  • As you've noticed, the Monitor.Enter/Exit are thread-affine.

    In their series on creating async-friendly coordination primitives, Stephen includes an AsyncLock that should be what you're looking for AFAICT.