我已经通过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()函数中并没有阻止错误的发生。
答案 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();
}
}