私は名前付きシステムミューテックスを使って2つのプロセスを同期させています。これは私が現在、自分のアプリケーション内のミューテックスを取得しています方法です:MutexName
名前付きシステムミューテックスが存在しない場合ミューテックスを取得する際の競合状態を回避する方法は?
using System.Threading;
public static bool AcquireMutex()
{
// Protect against double acquisitions
if (MyMutex != null)
{
throw new ApplicationException("Failed to acquire mutex");
}
try
{
// See if a named system mutex has already been created - if it has,
// wait a short amount of time for its release.
MyMutex = Mutex.OpenExisting(MutexName);
if (!MyMutex.WaitOne(TimeSpan.FromSeconds(2), false))
{
// MyMutex still being held
MyMutex = null;
return false;
}
}
catch
{
// MyMutex doesn't exist so create it
MyMutex = new Mutex(true, MutexName);
}
return true;
}
OpenExisting
は、私のアプリケーションは、それを作成することができ、例外がスローされます。
しかし、OpenExisting
がスローすると、new Mutex
の呼び出しの前に小さいウィンドウがあり、他のアプリケーションがそのミューテックスを取得している可能性があります。
この競合状態を回避し、このコードをより信頼できるものにする最良の方法は何ですか?
同僚は彼がコード内でWin32 Platform SDKのCreateMutex
(同期が必要な他のプロセス)を使用していると述べました。ただし、これは.NET Frameworkによってネイティブにサポートされているようには見えません。だから私はそれが私のコードのための最善の解決策であるとは思わない。 @デビッドシュワルツからの回答をもとに
更新
、ここに私の新しいコードは次のとおりです。
public static bool AcquireMutex()
{
// Protect against double acquisitions
if (MyMutex != null)
{
throw new ApplicationException("Failed to acquire mutex");
}
bool createdNew;
MyMutex = new Mutex(true, MutexName, out createdNew);
if (createdNew)
{
// Mutex was created so ownership is guaranteed; no need to wait on it.
return true;
}
try
{
if (!MyMutex.WaitOne(TimeSpan.FromSeconds(2), false))
{
MyMutex = null;
return false;
}
}
catch (AbandonedMutexException)
{
// Other application was aborted, which led to an abandoned mutex.
// This is fine, as we have still successfully acquired the mutex.
}
return true;
}
はい、これは機能しません。プロセスの1つをボス、それを作成するボスにする必要があります。 1つ、通常は最初のものを選んでください。他のプロセスがそれを開くことができない場合、本当に間違ったことがあります。それは待つ必要がある。 –
@ハンス - 私はDavid Schwartzの答えに基づいて変更を加えました。私の最新のコードを見て、それが正しいかどうか教えてください。 – LeopardSkinPillBoxHat
AbandonedMutexExceptionは、何かが重大に間違っている場合にのみスローされます。私は上記のコードのようにそれを沈黙させませんが、私のグローバル例外ハンドラはそれをさらに解析するためにログに記録させます。参照してください:https://msdn.microsoft.com/en-us/library/system.threading.abandonedmutexexception(v=vs.110).aspx –