C++ では簡単に解決できる質問がありますが、C# ではまだ適切な解決策が見つかりません。
2 つのオブジェクトをロックする必要がある関数 foo があり、この関数は逆の順序で引数を使用して呼び出すことができます。
static void foo(object o1, object o2)
{
lock (o1)
{
lock (o2)
{
...
}
}
}
static void bar(object a, object b)
{
ThreadPool.QueueUserWorkItem(s => foo(a, b));
ThreadPool.QueueUserWorkItem(s => foo(b, a));
}
これは、デッドロックを作成するための本による方法です。これを修正する標準的な方法は、オブジェクトを常に同じ順序でロックすることです。C++ ではポインターを比較することができましたが、「安全な」C# では非常に醜い解決策しかわかりませんMonitor.TryEntry
(以下を参照)。もっと良いものはありますか?Equals
オブジェクトは変更可能であり、 、GetHashCode
、 に依存できないことに注意してくださいIComparable
。
static void foo(object o1, object o2)
{
const int Timeout = 1000;
while (true)
{
if (Monitor.TryEnter(o1, Timeout))
{
try
{
if (Monitor.TryEnter(o2, Timeout))
{
try
{
...
return;
}
finally
{
Monitor.Exit(o2);
}
}
}
finally
{
Monitor.Exit(o1);
}
}
}
}