C# で排他制御を行う場合、lock
を使うことが多いと思いますが、ロックを取得できなかった場合に待機せず、即タイムアウトにしたい場合の方法です。
lock
だとタイムアウトを設定できないので、Monitor.TryEnter
を使います。
bool acquiredLock = false;
try
{
Monitor.TryEnter(lockObject, 0, ref acquiredLock);
if (acquiredLock)
{
// ロック取得に成功したときの処理
}
else
{
// ロック取得に失敗したときの処理
}
}
finally
{
if (acquiredLock) Monitor.Exit(lockObject);
}
一応動作確認
var lockTest = new LockTest();
Parallel.For(0, 99, i =>
{
lockTest.Hoge(i);
});
Console.WriteLine("完了");
Console.ReadKey();
class LockTest
{
object lockObject = new object();
int count = 0;
public void Hoge(int i)
{
bool acquiredLock = false;
try
{
Monitor.TryEnter(lockObject, 0, ref acquiredLock);
if (acquiredLock)
{
// ロック取得に成功したときの処理
count++;
Console.WriteLine($"i={i}, {count}");
Thread.Sleep(100);
}
else
{
// Console.WriteLine($"ロック取得失敗");
}
}
finally
{
if (acquiredLock) Monitor.Exit(lockObject);
}
}
}
実行結果
i=24, 1
i=64, 2
i=65, 3
i=66, 4
i=67, 5
i=68, 6
i=69, 7
i=70, 8
i=71, 9
完了
参考 URL
- https://webcache.googleusercontent.com/search?q=cache:ox1szN9XcI4J:https://qa.ccn-catv.co.jp/qa6224401.html+&cd=13&hl=ja&ct=clnk&gl=jp&client=firefox-b-d
- https://qiita.com/kenji-yokoi/items/2b47e7f9671dfc2e4803
- https://docs.microsoft.com/ja-jp/dotnet/api/system.threading.monitor.tryenter?view=netframework-4.7.2