只是写了一个简单的程序,必须一次处理完毕,所以通过使用一个键入的 Mutex
用一个特定的名字。代码(简化)是这样的。
static readonly string APP_NAME = "MutexSample";
static void Main(string[] args)
{
Mutex mutex;
try
{
mutex = Mutex.OpenExisting(APP_NAME);
// At this point, with no exception,
// the Mutex is acquired, so there is another
// process running
// Environment.Exit(1); or something
}
catch (WaitHandleCannotBeOpenedException)
{
// If we could not acquire any mutex with
// our app name, let's create one
mutex = new Mutex(true, APP_NAME);
}
Console.ReadKey(); // Just for keeping the application up
// At some point, I just want to release
// the mutex
mutex.ReleaseMutex();
}
我的第一次尝试是将 Mutex
喜欢 new Mutex(false, APP_NAME)
但叫 mutex.ReleaseMutex()
抛出了一个异常
System.ApplicationException: 'Object synchronization method was called from an unsynchronized block of code.'
刚刚注意到,构造函数的第一个参数(initiallyOwned
)标志着当前的线程是否正在创建这个 Mutex
毫不奇怪,一个线程不能释放一个 Mutex
的线程。
所以把这个参数改为 true
修正了这个问题,如上面的代码所示。
好吧,我的问题是,这个参数的全部意义是什么?我的意思是,我什么时候需要创建一个新的参数?Mutex
我无法释放它。而且,如果我把参数 initiallyOwned
到 false
谁才是真正的主人 Mutex
?
谢谢,我只是写了一个简单的程序,必须每次处理一次,所以通过使用特定名称的键控Mutex来实现。
没有人拥有一个 Mutex
,除非有人通过调用它的方法获得了 WaitOne
. 通过 initiallyOwned: true
是试图立即获得一个新创建的 Mutex
但这是有问题的。从... 文件:
你不应该使用这个构造函数来请求初始所有权,除非你能确定线程将创建命名的mutex。
还有 超负荷 接受三个参数。
public Mutex (bool initiallyOwned, string name, out bool createdNew);
...但更简单的是,只需创建一个新的函数 Mutex
在没有初始所有权的情况下,以后当你准备好被封杀时再获得它(以防它恰好被别人获得)。
mutex = new Mutex(initiallyOwned: false, APP_NAME);
mutex.WaitOne(); // Potentially blocking
我何时需要创建一个
Mutex
我无法释放它。
这个问题实在是太宽泛了。但一个不那么宽泛的问题是:
我怎样才能释放一个...
Mutex
当我创建它时,它并不是最初拥有的?
答案很简单:只需取得 Mutex
之后 你创造它。然后你就可以释放它。
而且,如果我把参数
initiallyOwned
到假,那Mutex到底是谁的?
这要看 Mutex
已经被其他线程或进程创建和获取。如果没有,那么 无人 拥有它,而你的代码将能够在以后获得它。
当然,对于你所处理的场景,你不一定要获取这个东西。Mutex
. 通常的做法是尝试 创造 的 Mutex
与 该构造函数. 第三个参数将被设置,如果你的代码真的创建了 Mutex
. 你从来没有真正需要获得它;你只是使用的事实,操作系统将确保该 Mutex
只被创建一次。
请注意,关于用.NET编写单实例程序,已经有很多非常好的建议。我强烈建议您回顾这里的信息。创建单实例WPF应用程序的正确方法是什么? 如何将程序限制为单实例?