C# 互斥不能正常工作
所以这段代码在program.cs中,应该检查连接是否可用,以及是否有另一个实例正在运行。如果有,消息框会通知用户,并询问用户是否确定要打开应用程序。下一个问题是: 我打开应用程序,然后再次打开,消息框显示,但什么也没发生。我重复这个过程,只有在4-5次后它才能工作。然后,如果我再次打开,它将打开两个实例C# 互斥不能正常工作,c#,mutex,C#,Mutex,所以这段代码在program.cs中,应该检查连接是否可用,以及是否有另一个实例正在运行。如果有,消息框会通知用户,并询问用户是否确定要打开应用程序。下一个问题是: 我打开应用程序,然后再次打开,消息框显示,但什么也没发生。我重复这个过程,只有在4-5次后它才能工作。然后,如果我再次打开,它将打开两个实例 static void Main() { Application.EnableVisualStyles(); Application.SetCompa
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SqlConnection con123 = new SqlConnection(con123.Metoda());
Mutex mut = null;
try
{
mut = Mutex.OpenExisting("Tray minimizer");
}
catch
{
}
if (mut == null)
{
mut = new Mutex(true, "Tray minimizer");
Application.Run(new Form1());
//Tell GC not to destroy mutex until the application is running and
//release the mutex when application exits.
GC.KeepAlive(mut);
mut.ReleaseMutex();
}
else
{
//The mutex existed so exit
mut.Close();
DialogResult result = MessageBox.Show("AApplication is already working!Do you want to reopen it?", "Caution!", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName("Name of application"))
{
try
{
p.Kill();
// p.WaitForExit(); // possibly with a timeout
Application.Run(new Form1());
}
catch (Win32Exception winException)
{
// process was terminating or can't be terminated - deal with it
}
catch (InvalidOperationException invalidException)
{
// process has already exited - might be able to let this one go
}
}
}
//if (result == DialogResult.Cancel)
//{
//}
}
try
{
con123.Open();
con123.Close();
}
catch
{
MessageBox.Show("Cant connect to server!!!", "Error!");
Application.Exit();
}
我会做一些更像:
bool mutexCreated = true;
using (Mutex mutex = new Mutex(true, "eCS", out mutexCreated))
{
if (mutexCreated)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SqlConnection con123 = new SqlConnection(con123.Metoda());
Application.Run(new Form1());
}
else
{
DialogResult result =
MessageBox.Show("AApplication is already working!Do you want to reopen it?", "Caution!",
MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName("Name of application"))
{
try
{
p.Kill();
Application.Run(new Form1());
}
catch (Win32Exception winException)
{
// process was terminating or can't be terminated - deal with it
}
catch (InvalidOperationException invalidException)
{
// process has already exited - might be able to let this one go
}
}
}
}
try
{
con123.Open();
con123.Close();
}
catch
{
MessageBox.Show("Cant connect to server!!!", "Error!");
Application.Exit();
}
}
您的版本存在的问题是,可能会在不适当的时间收集互斥
foreach(Process)
循环中启动应用程序,这意味着如果有多个进程已经在运行(可能所有进程都带有消息框),您将为每个进程启动应用程序else
案例应该类似于以下伪代码:
dialogResult = MessageBox(...);
if (dialogResult == OK)
{
foreach (var p in ...)
{
// Todo: make sure you do not kill the current process!
p.Kill();
}
// now run the application
Application.Run(new Form1());
// now release the mutex
mut.Release();
}
else
{
mut.Close();
}
该伪代码仍然需要一些异常处理,以确保在发生异常时正确释放互斥锁。这能解决您的问题吗?我没有使用
OpenExisting
,它没有文档保证在失败时返回null
,而是使用Mutex
构造函数,该构造函数将输出bool
,以确定互斥体是创建的还是已经存在。启动应用程序并对其执行任何操作(根据我看到的部分猜测)都会移动到与创建互斥锁或关闭现有实例相关的所有操作下方
现在的步骤如下:
runApp
变量初始化为trueMutex
- 如果未创建
互斥体,则该互斥体已存在
- 询问用户是否要退出,等待互斥锁可用(表示已完成强制退出现有应用程序实例)
- 如果他们不想退出,请将
设置为runApp
false
runApp
标志是否仍然为真
- 如果为true,则运行应用程序。返回后(表单退出),尝试连接 注意,这可能有一个错误,我不知道你是否打算阻止,因为你在应用程序中
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SqlConnection con123 = new SqlConnection(con123.Metoda());
string ProgramName = "Tray minimizer.exe";
bool mutCreated = false;
Mutex mut = new Mutex(true, ProgramName, out mutCreated);
bool runApp = true;
if (!mutCreated)
{
DialogResult result = MessageBox.Show("Application is already working! Do you want to reopen it?", "Caution!", MessageBoxButtons.OKCancel);
if (result == DialogResult.OK)
{
foreach (Process p in System.Diagnostics.Process.GetProcessesByName(ProgramName))
{
try
{
p.Kill();
}
catch { }
}
mut.WaitOne(); // Wait for ownership of the mutex to be released when the OS cleans up after the process being killed
}
else
{
runApp = false;
}
}
if (runApp)
{
Application.Run(new Form1());
try
{
con123.Open();
con123.Close();
}
catch
{
MessageBox.Show("Cant connect to server!!!", "Error!");
Application.Exit();
}
mut.ReleaseMutex();
}
好的,那么你的问题是什么?到目前为止,你已经讲了一个故事,但你还没有问任何问题。我会将这些异常记录在某个地方,如果你有如此多的空捕捉,那么你可能会在某个地方遇到异常。它工作不正常,我的意思是它不一致。它每五次工作一次,我不知道为什么。Kevin我这么做了,它什么也抓不到。首先,你一定要清理你的代码,清除所有空的
catch
es,并正确处理异常。