Почему я не могу использовать оператор await в теле оператора блокировки?

Ключевое слово await в C # (.NET Async CTP) не допускается из инструкции блокировки.

Из MSDN :

Выражение ожидания не может использоваться в синхронной функции, в выражении запроса , в блоке catch или finally оператора обработки исключений , в блоке оператора блокировки или в небезопасном контексте.

Я полагаю, что это либо сложно, либо невозможно реализовать команде компилятора по какой-то причине.

Я попытался обойтись с помощью оператора using:

class Async
{
    public static async Task Lock(object obj)
    {
        while (!Monitor.TryEnter(obj))
            await TaskEx.Yield();

        return new ExitDisposable(obj);
    }

    private class ExitDisposable : IDisposable
    {
        private readonly object obj;
        public ExitDisposable(object obj) { this.obj = obj; }
        public void Dispose() { Monitor.Exit(this.obj); }
    }
}

// example usage
using (await Async.Lock(padlock))
{
    await SomethingAsync();
}

Однако это не работает должным образом. Вызов Monitor.Exit в ExitDisposable.Dispose блокируется на неопределенный срок (большую часть времени), вызывая взаимоблокировки, когда другие потоки пытаются получить блокировку. Я подозреваю, что ненадежность моей работы и причина, по которой операторы ожидания не разрешены в операторе блокировки, как-то связаны.

Кто-нибудь знает , почему await не допускается в теле инструкции блокировки?

317
задан Kevin 30 September 2011 в 04:23
поделиться