我完全被这里难过了。我有一大堆代码依赖于互斥锁来保护它。当我在我的开发机器和我的测试机器上运行这一块代码时它工作正常。但是当我把它推到生产机器上时它就失败了。
但是这里是踢球者,它曾经工作过,我没有对这个特定的块进行任何代码更改。 但等等还有更多!我有第二个进程,它使用完全相同的代码块,它工作得很好!
互斥量声明为:
Mutex _mutex = new Mutex(false, "SendTextMessage_11A52B63-4FC6-46DF-B72C-C45B225D4143");
使用它的代码块是:
public override void ForwardTextMessagesToDevice()
{
Trace.WriteLine("Here1");
if (!_mutex.WaitOne(30000))
{
Trace.WriteLine("Here2");
Trace.WriteLine(String.Format("return mutex ForwardTextMessage: {0} {1}", this.Name, DateTime.Now));
return;
}
try
{
Trace.WriteLine("Here3");
ScheduledReports();
}
finally
{
Trace.WriteLine("Here4");
_mutex.ReleaseMutex();
}
跟踪输出是:
Here1
Here2
return mutex ForwardTextMessage: Method 2/11/2013 3:59:06 PM
Here1
Here2
return mutex ForwardTextMessage: Method 2/11/2013 4:00:06 PM
Mutex似乎立即被锁定在门外。我的印象是mutex只在线程之间共享,并在进程退出时被销毁,因此共享相同互斥锁的两个独立进程应该是好的,对吧?此外,如果应用程序在互斥锁被释放之前崩溃,是否会导致此行为?
编辑:我差点忘了。以前我的应用程序随机崩溃了,我不得不强制退出它。答案 0 :(得分:2)
Mutex似乎立即被锁定在门外。我的印象是mutex只在线程之间共享,并在进程退出时被销毁,因此共享相同互斥锁的两个独立进程应该是好的,对吧?
没有。 命名互斥实例在所有进程之间共享。另一个进程可以锁定互斥锁。
来自Mutex constructor you are using的文档:
互斥锁有两种类型:本地互斥锁和命名系统互斥锁。如果使用接受名称的构造函数创建Mutex对象,则它与该名称的操作系统对象关联。命名系统互斥体在整个操作系统中都是可见的,可用于同步进程的活动。
至于你的第二个问题:
此外,如果应用程序在互斥锁被释放之前崩溃,是否会导致此行为?
Mutex的文档涵盖了这一点:
如果线程在拥有互斥锁时终止,则称该互斥锁被放弃。互斥锁的状态设置为发出信号,下一个等待的线程获得所有权。如果没有人拥有互斥锁,则会发信号通知互斥锁的状态。从.NET Framework 2.0版开始,在获取互斥锁的下一个线程中抛出AbandonedMutexException。在.NET Framework 2.0版之前,没有抛出任何异常。
在应用程序终止的情况下,应将互斥锁标记为已放弃。尝试获取Mutex
应该会引发AbandonedMutexException
。