2

我在这里完全被难住了。我有一大段代码依赖互斥锁来保护它。当我在我的开发机器和测试机器上运行这段代码时,它工作正常。但是当我把它推到生产机器上时它失败了。

但这是踢球者,它曾经可以工作,我没有对这个特定的块进行任何代码更改。但是等等还有更多!我有第二个进程,它使用完全相同的代码块,它工作得很好!

互斥体声明如下:

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

互斥锁似乎立即被锁在门外。我的印象是互斥锁只在线程之间共享,并且在进程退出时被销毁,所以共享同一个互斥锁的两个独立进程应该是好的,对吧?此外,如果应用程序在互斥锁释放之前崩溃,是否会导致这种行为?

编辑:我差点忘了。以前我的应用程序随机崩溃了,我不得不强行退出它。

4

1 回答 1

2

互斥锁似乎立即被锁在门外。我的印象是互斥锁只在线程之间共享,并且在进程退出时被销毁,所以共享同一个互斥锁的两个独立进程应该是好的,对吧?

不会。 命名的 Mutex 实例在所有进程之间共享。另一个进程可以锁定互斥锁。

您正在使用的 Mutex 构造函数的文档中:

互斥体有两种类型:本地互斥体和命名系统互斥体。如果使用接受名称的构造函数创建 Mutex 对象,则它与该名称的操作系统对象相关联。命名系统互斥锁在整个操作系统中都是可见的,并且可以用来同步进程的活动。

至于你的第二个问题:

此外,如果应用程序在互斥锁释放之前崩溃,是否会导致这种行为?

Mutex的文档对此进行了介绍:

如果线程在拥有互斥锁时终止,则称该互斥锁被放弃。互斥体的状态设置为已发出信号,并且下一个等待线程获得所有权。如果没有人拥有该互斥体,则会发出该互斥体的状态信号。从 .NET Framework 2.0 版开始,在获取互斥锁的下一个线程中会引发 AbandonedMutexException。在 .NET Framework 2.0 版之前,没有引发异常。

在应用程序终止的情况下,互斥体应标记为已放弃。尝试获取Mutex应该提高AbandonedMutexException.

于 2013-02-12T00:15:46.817 回答