두 프로세스를 동기화하기 위해 명명 된 시스템 뮤텍스를 사용하고 있습니다. 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
이 throw되면 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;
}
예, 작동하지 않습니다. 프로세스 중 하나를 보스, 즉 보스로 만들어야합니다. 하나, 보통 첫 번째 하나를 선택하십시오. 다른 프로세스가 열 수 없다면 정말 잘못된 것이 있습니다. 기다려야 해. –
@ 한스 - David Schwartz의 대답을 기반으로 변경했습니다. 업데이트 된 코드를보고 올바르게 표시되는지 알려주십시오. – LeopardSkinPillBoxHat
AbandonedMutexException은 심각한 오류가있는 경우에만 throw됩니다. 위 코드 에서처럼 침묵하지 않을 것이지만 내 글로벌 예외 처리기가 추가 분석을 위해 기록하도록하십시오. 참조 : https://msdn.microsoft.com/en-us/library/system.threading.abandonedmutexexception(v=vs.110).aspx –