C#(.NET Async CTP)のawaitキーワードは、lockステートメント内からは許可されていません。
MSDNから:
await式は、同期関数、クエリ式、例外処理ステートメントのcatchまたはfinallyブロック、lockステートメントのブロック、または安全でないコンテキストでは使用できません。
これは、コンパイラチームが何らかの理由で実装するのが難しいか不可能であると思います。
usingステートメントで回避策を試みました。
class Async
{
public static async Task<IDisposable> 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();
}
ただし、これは期待どおりに機能しません。ExitDisposable.Dispose内のMonitor.Exitの呼び出しは、(ほとんどの場合)無期限にブロックされ、他のスレッドがロックを取得しようとするときにデッドロックが発生するようです。私の回避策の信頼性の低さと、ロックステートメントで待機ステートメントが許可されない理由は何らかの形で関連していると思います。
ロックステートメントの本文内で待機が許可されない理由を誰かが知っていますか?