我怎样才能摆脱废弃的互斥体?

时间:2014-08-27 23:30:11

标签: c# .net mutex

要点:

  

如果创建互斥锁的进程已经死亡并且已经消失,是否有办法清除互斥锁?

详细信息:

我使用互斥锁来确保我的应用只运行一个实例。

在测试一些新代码(进行自动更新)时,我运行了Environment.Exit(0)。在调试模式下运行时,我的互斥锁被清理干净了。

但是当我将构建更改为' Release'然后,在退出呼叫后,互斥锁保持不变,并被标记为放弃:

Abandoned Mutex

我已仔细检查以确保没有正在运行此互斥锁的进程。

现在每次运行我的应用程序时,它都认为互斥锁仍然存在,并且不会启动我的应用程序。 (它也崩溃了,因为它试图向"当前正在运行的应用程序实例发送消息以显示自己。)

我试图像这样释放互斥锁:

bool createdNew;
string applicationId = "18773:TestStudio";
var singleInstanceMutex = new Mutex(true, applicationId, out createdNew);

singleInstanceMutex.Close();  // Tried ReleaseMutex() too

但当然只是得到它然后释放它。

我知道我可以重新启动,但我正在寻求更好的解决方案以防生产中发生这种情况。

如果创建互斥锁的进程已经死亡并且已经消失,是否有办法清除互斥锁?

1 个答案:

答案 0 :(得分:0)

不知道这是否真的回答了你的问题,但这里是我用于此目的的代码:

  // Mutex object used to determine if there are multiple instances of this program running. 
  //  Note that this is a reference to a .Net Mutex object, not the Windows mutex itself.
  private static Mutex _onlyOneInstanceMutex;



  /// <summary>
  /// Method to test that there is not another instance of the program already running on this 
  /// machine, or at least in this Terminal Services session or Windows Vista / Windows 7 
  /// concurrent sessions session. If there is, a message box-style localized error message is 
  /// displayed and the value false is returned. This implies that this method should not be 
  /// used in programs that are run as a Windows service.
  /// 
  /// This implementation uses a .Net Mutex object in public storage to prevent it from being 
  /// garbage-collected. The name of the associated Windows mutex is simply the program name as 
  /// provided by the caller. Neither the .Net Mutex object nor the Windows mutex are ever 
  /// explicitly released; they remain in existence, perhaps in an "abandoned" state, until the 
  /// process that created them terminates.
  /// </summary>
  /// <returns>false if another instance running, otherwise true</returns>
  [SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive",
                   Justification = "Not sure if this is correct or not.")]
  public static bool TestOnlyOneInstance(string programName)
  {
     // Funny construct to prevent the Mutex from being garbage collected
     GC.KeepAlive(_onlyOneInstanceMutex);

     // Test if we are the first instance, and if so create the Windows mutex, making it 
     //  impossible for subsequent instances to successfully create their mutex
     bool firstInstance;
     _onlyOneInstanceMutex = new Mutex(false, programName, out firstInstance);
     if (firstInstance)
        return true;

     // Display a (possibly localized) error message, then return
     string errorMessage = MLocalizer.GetString("Error1", 
           "Another instance of this program is already running on this machine.") +
         "\n" + MLocalizer.GetString("Error2",
                                     "You cannot run two instances at the same time.") +
         "\n" + MLocalizer.GetString("Error3", "Please use the other instance.");
     MessageBox.Show(errorMessage, programName, MessageBoxButtons.OK, MessageBoxIcon.Error);
     return false;
  }

编辑:

我在代码和你的代码中只能看到的差异是我指定&#34;最初拥有&#34;假的,我对垃圾收集很有趣。

哦,我宣布Mutex是静态的。