排他制御を行う際、Monitor.TryEnter
と async/await
を使用すると上手く動作しなかったので調べていたところ、Interlocked.CompareExchange
を使ってもっと簡単かつ安全に実装できることがわかったのでメモしておきます。
参考にしたのは以下のページです。
やりたいこととしては、複数のスレッドから同時実行される可能性のある処理について、既にその処理を実行中の場合は即エラーを返したい(ロックが解放されるのを待たない)というものです。
サンプルコード
if(Interlocked.CompareExchange(ref running, 1, 0) != 0)
{
// ロック取得失敗
return;
}
try {
// 時間のかかる処理
await Task.Delay(TimeSpan.FromSeconds(5));
}
finally {
// ロックの解放
Interlocked.Exchange(ref running, 0);
}