当我想使用互斥锁强制我的程序的单个实例时,我遇到了问题。
我是一个带有WebBrowser控件的winform应用程序。如果满足某些条件,我需要自动重启。
我的问题是,如果我重新启动应用程序,互斥锁希望让我打开一个新实例(这并不总是发生)可能导致浏览器有一些异步方法,如导航。
但是我在退出申请活动中发布了Mutex。
这是我的代码:
static Mutex _mutex = new Mutex (false, "myprogramkey");
[STAThread]
private static void Main()
{
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
if(_mutex.WaitOne(TimeSpan.FromSeconds(5), true))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new RevolutionForm());
}
else
{
MessageBox.Show("Error!");
}
}
static void Application_ApplicationExit(object sender, EventArgs e)
{
_mutex.ReleaseMutex();
}
答案 0 :(得分:3)
框架很好地支持单实例应用程序。它支持好处,例如在运行中禁用它,在这里需要什么,以及在另一个实例启动时获取通知。您将要使用它来为您的第一个实例提供焦点。重写你的Program.cs代码:
using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices; // NOTE: add reference to Microsoft.VisualBasic
namespace WindowsFormsApplication1 {
class Program : WindowsFormsApplicationBase {
public Program() {
EnableVisualStyles = true;
MainForm = new Form1();
IsSingleInstance = true;
}
public static void Main(string[] args) {
Instance = new Program();
Instance.Run(args);
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) {
// Nicety, focus the single instance.
Instance.MainForm.Activate();
}
public static void Restart() {
// What you asked for. Use Program.Restart() in your code
Instance.IsSingleInstance = false;
Application.Restart();
}
private static Program Instance;
}
}
答案 1 :(得分:0)
尝试使用try..finally
来管理互斥锁。
我通常使用这种方法。与Application.Restart()
结合使用效果很好。
private const string ApplicationMutexName = "<myprogramkey>";
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
public static void Main()
{
RunApplicationPreservingSingleInstance();
}
private static void RunApplicationPreservingSingleInstance()
{
Mutex mutex = AcquireMutex();
if (mutex == null)
{
return;
}
try
{
RunApplication();
}
finally
{
mutex.ReleaseMutex();
}
}
private static Mutex AcquireMutex()
{
Mutex appGlobalMutex = new Mutex(false, ApplicationMutexName);
if (!appGlobalMutex.WaitOne(3000))
{
return null;
}
return appGlobalMutex;
}
private static void RunApplication()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
答案 2 :(得分:0)
我不确定你的情况究竟出了什么问题,但有些问题可能是:
try finally
关闭互斥锁以最大限度地更改正确的清理Mutex.WaitOne
会抛出AbandonedMutexException
而不是返回true
。在这种情况下,您可以继续使用错误框退出代码。Mutex
仅供用户使用)。示例强>
以下示例将要求您使用Program.Restart
重新启动应用程序。否则时间窗口仍然是问题。
static class Program
{
private static Mutex _mutex;
[STAThread]
static void Main()
{
_mutex = new Mutex(false, "myprogramkey");
try
{
try
{
if (!_mutex.WaitOne(1))
{
_mutex.Dispose();
_mutex = null;
MessageBox.Show("Error!");
return;
}
}
catch (AbandonedMutexException) { /* Mutex wasn't property released last time.*/ }
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
finally
{
if (_mutex != null)
{
_mutex.ReleaseMutex();
_mutex.Dispose();
}
}
}
public static void Restart()
{
if (_mutex != null)
{
_mutex.ReleaseMutex();
_mutex.Dispose();
_mutex = null;
Application.Restart();
}
}
}
答案 3 :(得分:0)
我这样做:
bool onlyInstance = false;
mutex = new System.Threading.Mutex(true, "qFluid", out onlyInstance);
int cntrSec = 0;
//per far funzionare restart ,aspetto per 3 sec per vedere se va via servizio
while (!onlyInstance & cntrSec < 3)
{
System.Threading.Thread.Sleep(1000);
cntrSec += 1;
}
if (!onlyInstance)
{
Xceed.Wpf.Toolkit.MessageBox.Show("The application is already arunning");
App.Current.Shutdown();
}