C#のawaitキーワード(.NET Async CTP)は、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の呼び出しは、他のスレッドがロックを取得しようとするため、(ほとんどの場合)無期限にブロックされ、デッドロックを引き起こしているようです。私の作業の信頼性が低いことと、awaitステートメントがlockステートメントで許可されていない理由は、どういうわけか関係しています。
ロック文の本文内でawaitが許可されない理由を誰かが知っていますか?