ReleaseMutex在单线程c#windows窗体应用程序中失败

时间:2015-11-19 10:56:53

标签: c# winforms mutex

我已经通过SO查看了这个问题,但其他实例似乎只涉及多线程应用程序问题。

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

这是我的代码:

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()函数中并没有阻止错误的发生。

2 个答案:

答案 0 :(得分:5)

从msdn中读取,您应该在true参数上传递initiallyOwned

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

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

因为应用程序的第一个实例想要拥有所有权(因此同一程序的其他实例,不能拥有它)。如果您没有所有权,则无法发布。如果您不能拥有所有权,因为已经获得了另一个实例,bMutexAcquired将返回false。

如果您将false传递给initiallyOwned参数。您只是创建互斥锁。然后,您必须使用WaitOne()获取(锁定)互斥锁,并ReleaseMutex()将其释放。

答案 1 :(得分: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(); 
   } 
}