Mutex 不会同时停止来自 运行 的两个程序实例
Mutex does not stop two instances of program from running at once
我正在尝试使用 Mutex 一次只允许我的程序的一个实例 运行。我重用了我正在编写的另一个程序中的 Mutex 代码,结果发现它并没有阻止我的程序的两个实例同时变为 运行。但是,我的 Mutex 代码在我的其他程序中有效。下面是Program.cs
的全部代码(打开文件的代码无关)。您能否解释一下我应该如何正确使用 Mutex 来防止我的程序的多个实例一次 运行?谢谢!
注意:我的原始代码基于这个 SO 答案:
using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace NTCSAttendanceKiosk
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Make a mutex and detect if another instance of the program is running
Mutex mutex = new Mutex(true, "AtteNTCSKioskMutex", out bool mutexResult);
if (!mutexResult)
{
// Exit if it's already running
return;
}
// Prevent the mutex from being released by the GC
GC.KeepAlive(mutex);
// Read the connection string from the file
try
{
SqlConnectionInfo.ConnectionString = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\kiosk_config\connection_string.txt");
}
catch (FileNotFoundException)
{
MessageBox.Show("The file connection_string.txt does not exist. Please place the connection string in that file and place it in <your user folder>\kiosk_config\. The kiosk program will now exit.", "Connection String File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (IOException)
{
MessageBox.Show("File I/O error when loading connection_string.txt. The kiosk program will now exit.", "File I/O Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// Read the kiosk location name from the file
try
{
SqlConnectionInfo.KioskLocation = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\kiosk_config\location.txt");
}
catch (FileNotFoundException)
{
MessageBox.Show("The file location.txt does not exist. Please place the kiosk location name in that file and place it in <your user folder>\kiosk_config\. The kiosk program will now exit.", "Connection String File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (IOException)
{
MessageBox.Show("File I/O error when loading location.txt. The kiosk program will now exit.", "File I/O Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Application.Run(new KioskForm());
}
}
}
您可以通过 运行 多个实例同时测试以下代码。
static void Main(string[] args)
{
using (var mutex = new Mutex(true, "UniqueSystemWideMutexName"))
{
//Timeout is set to zero so we don't block
if (!mutex.WaitOne(0))
{
Console.WriteLine("Program already running");
Console.ReadKey();
return;
}
Console.WriteLine("This is the only program running");
Console.ReadKey();
}
}
如果您出于某种原因无法使用 Dispose
,而 using
块为我们所做的,请务必调用 ReleaseMutex
.
您也可以使用 OpenExisting 检查互斥体是否已经创建,但对于这个简单的用例来说没有必要。
我正在尝试使用 Mutex 一次只允许我的程序的一个实例 运行。我重用了我正在编写的另一个程序中的 Mutex 代码,结果发现它并没有阻止我的程序的两个实例同时变为 运行。但是,我的 Mutex 代码在我的其他程序中有效。下面是Program.cs
的全部代码(打开文件的代码无关)。您能否解释一下我应该如何正确使用 Mutex 来防止我的程序的多个实例一次 运行?谢谢!
注意:我的原始代码基于这个 SO 答案:
using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace NTCSAttendanceKiosk
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Make a mutex and detect if another instance of the program is running
Mutex mutex = new Mutex(true, "AtteNTCSKioskMutex", out bool mutexResult);
if (!mutexResult)
{
// Exit if it's already running
return;
}
// Prevent the mutex from being released by the GC
GC.KeepAlive(mutex);
// Read the connection string from the file
try
{
SqlConnectionInfo.ConnectionString = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\kiosk_config\connection_string.txt");
}
catch (FileNotFoundException)
{
MessageBox.Show("The file connection_string.txt does not exist. Please place the connection string in that file and place it in <your user folder>\kiosk_config\. The kiosk program will now exit.", "Connection String File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (IOException)
{
MessageBox.Show("File I/O error when loading connection_string.txt. The kiosk program will now exit.", "File I/O Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// Read the kiosk location name from the file
try
{
SqlConnectionInfo.KioskLocation = File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\kiosk_config\location.txt");
}
catch (FileNotFoundException)
{
MessageBox.Show("The file location.txt does not exist. Please place the kiosk location name in that file and place it in <your user folder>\kiosk_config\. The kiosk program will now exit.", "Connection String File Not Found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
catch (IOException)
{
MessageBox.Show("File I/O error when loading location.txt. The kiosk program will now exit.", "File I/O Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Application.Run(new KioskForm());
}
}
}
您可以通过 运行 多个实例同时测试以下代码。
static void Main(string[] args)
{
using (var mutex = new Mutex(true, "UniqueSystemWideMutexName"))
{
//Timeout is set to zero so we don't block
if (!mutex.WaitOne(0))
{
Console.WriteLine("Program already running");
Console.ReadKey();
return;
}
Console.WriteLine("This is the only program running");
Console.ReadKey();
}
}
如果您出于某种原因无法使用 Dispose
,而 using
块为我们所做的,请务必调用 ReleaseMutex
.
您也可以使用 OpenExisting 检查互斥体是否已经创建,但对于这个简单的用例来说没有必要。