这种使用 c# Mutex class 的替代方式是否有任何损失?
Are there any loss in this alternative way of using c# Mutex class?
我有一个使用 Mutex 的应用程序(我没有写这个):
static void Main(string[] args)
{
Mutex mutex = null;
try
{
mutex = Mutex.OpenExisting("SINGLEINSTANCE");
if (mutex != null)
{
return;
}
}
catch (WaitHandleCannotBeOpenedException ex)
{
mutex = new Mutex(true, "SINGLEINSTANCE");
}
// critical section here
}
但我知道正确的做法是这样的:
private readonly Mutex m = new Mutex("SINGLEINSTANCE");
static void Main(string[] args) {
m.WaitOne();
try {
/* critical code */
}
finally {
m.ReleaseMutex();
}
}
之所以使用这个是因为这个应用程序只有一个进程可以同时运行。它是一个控制台应用程序,为 Web 应用程序执行一些异步作业。
这段代码正在制作中,我不想更改它,除非这段代码有什么大问题...有吗?
旧代码有一个竞争条件,两个进程可能会尝试同时启动,第二个启动的进程将抛出异常并在 new Mutex(true, "SINGLEINSTANCE");
行崩溃。如果互斥量已经存在并且您没有竞争条件,程序将正常退出并且永远不会执行临界区。
您的新代码无法编译,因为您没有为 Mutex
使用有效的构造函数,但是如果您传入了 false
,您的代码将等待之前的互斥体被释放它将继续执行关键部分,永远不会提前退出程序。
"Correct" 方法是结合这两种方法并尝试创建互斥锁,然后使用带有 out
参数的重载来查看您是否是它的所有者。
static void Main(string[] args)
{
bool taken;
using(Mutex mutex = new Mutex(true, "SINGLEINSTANCE", out taken))
{
if(!taken)
return;
try
{
// critical section here
}
finally
{
mutex.ReleaseMutex();
}
}
}
我有一个使用 Mutex 的应用程序(我没有写这个):
static void Main(string[] args)
{
Mutex mutex = null;
try
{
mutex = Mutex.OpenExisting("SINGLEINSTANCE");
if (mutex != null)
{
return;
}
}
catch (WaitHandleCannotBeOpenedException ex)
{
mutex = new Mutex(true, "SINGLEINSTANCE");
}
// critical section here
}
但我知道正确的做法是这样的:
private readonly Mutex m = new Mutex("SINGLEINSTANCE");
static void Main(string[] args) {
m.WaitOne();
try {
/* critical code */
}
finally {
m.ReleaseMutex();
}
}
之所以使用这个是因为这个应用程序只有一个进程可以同时运行。它是一个控制台应用程序,为 Web 应用程序执行一些异步作业。
这段代码正在制作中,我不想更改它,除非这段代码有什么大问题...有吗?
旧代码有一个竞争条件,两个进程可能会尝试同时启动,第二个启动的进程将抛出异常并在 new Mutex(true, "SINGLEINSTANCE");
行崩溃。如果互斥量已经存在并且您没有竞争条件,程序将正常退出并且永远不会执行临界区。
您的新代码无法编译,因为您没有为 Mutex
使用有效的构造函数,但是如果您传入了 false
,您的代码将等待之前的互斥体被释放它将继续执行关键部分,永远不会提前退出程序。
"Correct" 方法是结合这两种方法并尝试创建互斥锁,然后使用带有 out
参数的重载来查看您是否是它的所有者。
static void Main(string[] args)
{
bool taken;
using(Mutex mutex = new Mutex(true, "SINGLEINSTANCE", out taken))
{
if(!taken)
return;
try
{
// critical section here
}
finally
{
mutex.ReleaseMutex();
}
}
}