互斥锁杀死应用程序
Mutex kills application
这是我的代码:
protected override async void OnStartup(StartupEventArgs e)
{
// Used to check if we can create a new mutex
bool newMutexCreated = false;
try
{
// Create a new mutex object with a unique name
mutex = new Mutex(false, MutexName, out newMutexCreated);
}
catch (Exception ex)
when (ex is UnauthorizedAccessException ||
ex is IOException ||
ex is WaitHandleCannotBeOpenedException ||
ex is ArgumentException)
{
Logger.Error("Error while launching application. Failed to check for other instances.", ex);
Shutdown((int)ExitCode.ApplicationAlreadyRunning);
}
// When the mutex is created for the first time
// we run the program since it is the first instance.
if (newMutexCreated)
{
await ContinueStartup(e);
return;
}
else
{
// Otherwise we get the first instance with that process name,
Process[] currentProcesses = Process.GetProcessesByName(AssemblyName);
IntPtr mainWindowHandle = currentProcesses[0].MainWindowHandle;
if (mainWindowHandle != IntPtr.Zero)
{
// maximize it, if it was minimized, and set it to foreground.
Logger.Info("Another instance of the application is already running.");
ShowWindow(mainWindowHandle, WindowShowNormal);
SetForegroundWindow(mainWindowHandle);
}
// Then shutdown this instance.
Logger.Info("Shutting down.");
Shutdown((int)ConsoleModeExitCode.ApplicationAlreadyRunning);
}
}
protected override void OnExit(ExitEventArgs e)
{
Logger.Info("Exiting application.");
// Close mutex.
mutex.Dispose();
base.OnExit(e);
}
这里发生的是我的应用程序应该启动一次。在 运行ning 期间,每次尝试启动新实例时都应将第一个实例置于最前面。
但实际发生的情况是:在 2-10 次启动尝试后,第一个实例的 GUI 被终止,该进程仍在 运行ning 并阻塞 Mutex,只能在 TaskManager 中终止。如果我尝试在 VisualStudio 中调试此行为和 运行 应用程序,它永远不会发生。尝试打开应用程序 50 次永远不会终止它,所以我无法跟踪似乎发生的事件。
这是 GarbageCollector 的正常行为吗?如果挂起,它会杀死第一个实例吗?
还是我遗漏了什么?
好的,正如@Luaan 提到的,问题不在于 Mutex。
我用这个解决方案修复了我的代码:
ShowWindowAsync
并且对句柄的 IntPtr 值的处理略有不同似乎使这种 方式更 稳定。从此无法崩溃。对我来说,这已经足够稳定了:)
这是我的代码:
protected override async void OnStartup(StartupEventArgs e)
{
// Used to check if we can create a new mutex
bool newMutexCreated = false;
try
{
// Create a new mutex object with a unique name
mutex = new Mutex(false, MutexName, out newMutexCreated);
}
catch (Exception ex)
when (ex is UnauthorizedAccessException ||
ex is IOException ||
ex is WaitHandleCannotBeOpenedException ||
ex is ArgumentException)
{
Logger.Error("Error while launching application. Failed to check for other instances.", ex);
Shutdown((int)ExitCode.ApplicationAlreadyRunning);
}
// When the mutex is created for the first time
// we run the program since it is the first instance.
if (newMutexCreated)
{
await ContinueStartup(e);
return;
}
else
{
// Otherwise we get the first instance with that process name,
Process[] currentProcesses = Process.GetProcessesByName(AssemblyName);
IntPtr mainWindowHandle = currentProcesses[0].MainWindowHandle;
if (mainWindowHandle != IntPtr.Zero)
{
// maximize it, if it was minimized, and set it to foreground.
Logger.Info("Another instance of the application is already running.");
ShowWindow(mainWindowHandle, WindowShowNormal);
SetForegroundWindow(mainWindowHandle);
}
// Then shutdown this instance.
Logger.Info("Shutting down.");
Shutdown((int)ConsoleModeExitCode.ApplicationAlreadyRunning);
}
}
protected override void OnExit(ExitEventArgs e)
{
Logger.Info("Exiting application.");
// Close mutex.
mutex.Dispose();
base.OnExit(e);
}
这里发生的是我的应用程序应该启动一次。在 运行ning 期间,每次尝试启动新实例时都应将第一个实例置于最前面。
但实际发生的情况是:在 2-10 次启动尝试后,第一个实例的 GUI 被终止,该进程仍在 运行ning 并阻塞 Mutex,只能在 TaskManager 中终止。如果我尝试在 VisualStudio 中调试此行为和 运行 应用程序,它永远不会发生。尝试打开应用程序 50 次永远不会终止它,所以我无法跟踪似乎发生的事件。
这是 GarbageCollector 的正常行为吗?如果挂起,它会杀死第一个实例吗? 还是我遗漏了什么?
好的,正如@Luaan 提到的,问题不在于 Mutex。 我用这个解决方案修复了我的代码:
ShowWindowAsync
并且对句柄的 IntPtr 值的处理略有不同似乎使这种 方式更 稳定。从此无法崩溃。对我来说,这已经足够稳定了:)