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

本文关键字:应用程序 失败 窗体 c#windows 单线程 ReleaseMutex | 更新日期: 2023-09-27 18:22:42

我已经查看了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()函数中并不能阻止错误的发生。

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

从msdn读取时,应在initiallyOwned参数上传递true

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()来释放它

您必须获得Mutex。收购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(); 
   } 
}