2015-11-19 162 views
2

我已经经历了这么看了这个问题,但其他实例似乎只涉及到多线程应用程序的问题。ReleaseMutex在单线程的C#Windows失败窗体应用程序

我的应用程序是一个简单单的形式,单线程应用程序,我只是用一个互斥体,以确保只有一个实例在主机系统上运行。

这是我的代码:

using System; 
using System.Reflection; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Windows.Forms; 

namespace UPGRADE 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      Mutex mSpartacus; 

      Assembly myAssembly = Assembly.GetExecutingAssembly(); 
      GuidAttribute ga = (GuidAttribute)myAssembly.GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0); 
      string sMyGUID = ga.Value.ToString().ToUpper(); 
      string sMutexId = @"Global\{" + sMyGUID + @"}"; 

      bool bMutexAcquired = false; 
      mSpartacus = new Mutex(false, sMutexId, out bMutexAcquired); 
      if (!bMutexAcquired) 
      { 
       MessageBox.Show("Upgrade.exe is already running.\n\nOnly one instance can run at once.", "Already running"); 
       return; 
      } 

      try 
      { 
       Application.EnableVisualStyles(); 
       Application.SetCompatibleTextRenderingDefault(false); 
       Form1 myForm = new Form1(); 
       Application.Run(myForm); 
      } 
      finally 
      { 
       mSpartacus.ReleaseMutex(); 
      } 
     } 
    } 
} 

它未能在ReleaseMutex()与误差对象同步方法是从代码不同步块称为调用。

有人可以解释我做错了什么吗?互斥体最初是一个静态变量,但将它放入Main()函数内并不能阻止发生错误。

回答

5

由于从MSDN阅读,你应该在initiallyOwned参数传递true

https://msdn.microsoft.com/en-us/library/bwe34f1k(v=vs.110).aspx

mSpartacus = new Mutex(true, sMutexId, out bMutexAcquired); 

由于应用程序的第一个实例都想拥有所有权(同一程序的那么其他情况下,不能拥有它)。如果你没有所有权,你不能释放它。如果你不能拥有所有权,因为另一个实例已经获得它,bMutexAcquired返回false。


如果传递falseinitiallyOwned参数。你只是创建互斥体。然后您必须使用WaitOne()来获取(锁定)互斥锁并释放它。

+0

非常感谢吉荣 - 解决了它。 – intDattashame

+1

我在SO上读过关于它的最佳解释 –

1

您必须获得Mutex。有获取互斥锁,双向的:

  • 使用WaitOne方法
  • 使用构造函数参数initiallyOwned

下面是一个例子使用WaitOne方法:

const string AppId = "Global\\1DDFB948-19F1-417C-903D-BE05335DB8A4"; // Unique per application 
static void Main(string[] args) 
{ 
    using (Mutex mutex = new Mutex(false, AppId)) 
    { 
     if (!mutex.WaitOne(0)) 
     { 
      Console.WriteLine("2nd instance"); 
      return; 
     } 
     Console.WriteLine("Started"); 
     Console.ReadKey(); 
    } 
} 
相关问题