Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 跨进程互斥实例_C#_.net_Concurrency_Mutex - Fatal编程技术网

C# 跨进程互斥实例

C# 跨进程互斥实例,c#,.net,concurrency,mutex,C#,.net,Concurrency,Mutex,刚刚编写了一个简单的程序,必须一次处理一次,所以通过使用带有特定名称的键控互斥锁来实现这一点。 代码(简化)如下所示 static readonly string APP_NAME = "MutexSample"; static void Main(string[] args) { Mutex mutex; try { mutex = Mutex.OpenExisting(APP_NAME); // At this point, with

刚刚编写了一个简单的程序,必须一次处理一次,所以通过使用带有特定名称的键控
互斥锁来实现这一点。
代码(简化)如下所示

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();
}
我的第一次尝试是实例化
互斥体
,比如
新互斥体(false,APP_NAME)
,但调用
互斥体。ReleaseMutex()
引发异常

System.ApplicationException:“从未同步的代码块调用了对象同步方法。”

刚才注意到构造函数的第一个参数(
initiallyOwned
)标记创建
互斥体的当前线程是否拥有它,并且,毫不奇怪,线程不能释放不属于该线程的
互斥体

因此,将此参数更改为
true
修复了该问题,如上面的代码所示

我的问题是,这个参数的全部意义是什么?我的意思是,我什么时候需要创建一个我无法释放的
互斥锁。
而且,如果我将参数
initiallyOwned
设置为
false
,那么谁真正拥有该
互斥锁呢

谢谢

我什么时候需要创建一个我无法释放的
互斥锁

这个问题实在太宽泛了。但一个不太宽泛的问题是:

当我创建互斥锁时,如何释放一个最初不属于我的互斥锁

答案很简单:创建互斥锁后,只需获取它。然后你可以释放它

如果我将参数
initiallyOwned
设置为false,那么谁真正拥有互斥锁

这取决于
Mutex
是否已经被其他线程或进程创建和获取。如果不是,那么就没有人拥有它,您的代码以后也可以获得它

当然,对于您正在处理的场景,您甚至不一定要获取
互斥体。通常的方法是尝试使用创建
Mutex
。如果您的代码实际创建了
互斥体
,则将设置第三个参数。你永远不需要真正地获得它;您只是使用了这样一个事实,即操作系统将确保
互斥体只创建一次

请注意,关于使用.NET编写单实例程序,已经有很多非常好的建议。我强烈建议您查看此处的信息:


没有人拥有互斥体,除非它是由某人通过调用其方法获得的。传递
initiallyOwned:true
是试图立即获取新创建的
互斥体,但这是有问题的。从:

您不应该使用此构造函数来请求初始所有权,除非您可以确定线程将创建命名互斥体

还有一种方法可以接受三个参数:

public Mutex (bool initiallyOwned, string name, out bool createdNew);
…但更简单的方法是,只创建
互斥体,而不具有初始所有权,然后在您准备被阻止时获取它(以防它碰巧被其他人获取)


好吧,可能更聪明的方法是创建
互斥体
,然后尝试
WaitOne
并查看
布尔
结果?@VRoxa yeap,调用
WaitOne
,并为
毫秒超时
参数设置零值当然是一个灵活的选择!只是为了完成。作为对文件引用的回应。。。在我在上面的第一个示例中创建
互斥体时,我完全确定我可以创建命名的
互斥体,不是吗?因此,这符合我的上下文。我认为您的代码在
mutex=mutex.OpenExisting(APP\u NAME)
mutex=new mutex(true,APP\u NAME)
行之间有一个竞争条件。另一个进程可以同时创建和获取互斥对象的所有权。这种可能性很小,但我肯定不会在生产环境中运行这段代码。
mutex = new Mutex(initiallyOwned: false, APP_NAME);
mutex.WaitOne(); // Potentially blocking