gpt4 book ai didi

c# - 如果我在以下代码中重用现有的 Mutex,为什么会得到一个新创建的 Mutex?

转载 作者:行者123 更新时间:2023-11-30 20:28:24 26 4
gpt4 key购买 nike

或不同的标题:

为什么处置获得的 Mutex 会破坏它?

我有以下代码,真正的代码在几个方法之间产生,并在这个方法休眠的地方做事:

        bool createdNew;
using (Mutex mutex = new Mutex(true, "Global\\AAA", out createdNew))
{
if (!createdNew)
{
throw new InvalidOperationException();
}
}

Thread.Sleep(15000);

using (Mutex mutex = new Mutex(false, "Global\\AAA", out createdNew))
{
if (!createdNew)
{
mutex.ReleaseMutex();
}
else
{
throw new InvalidOperationException();
}
}

我期待第一次得到 createdNew = true,第二次得到 false,但我两次都得到 true。

它与处理有关,如果我不处理 Mutex 那么一切都会按预期工作,但正如我在几个地方发现的那样 here处理 Mutex 不会释放它(所以我猜它不会破坏它,因为当前线程获取了 Mutex)。

那么,为什么处理会破坏获得的 Mutex

最佳答案

因为互斥锁在最后一个句柄关闭时被销毁(reference):

Use the CloseHandle function to close the handle. The system closes the handle automatically when the process terminates. The mutex object is destroyed when its last handle has been closed.

这就是您的示例中发生的情况 - 您创建了互斥量,然后(使用 using)关闭了它的唯一句柄,因此它被销毁了。

请注意,您不应该像这样创建互斥量并在不释放互斥量的情况下关闭它的句柄:

Mutex mutex = new Mutex(true, "Global\\AAA", out createdNew)

这是说 - 如果互斥量不存在,创建它并赋予该线程所有权。因此,如果 createdNew 在此调用后为真 - 您拥有此互斥锁,因此应该释放它。通过关闭句柄,您要么只是销毁互斥锁​​(但这是无用的场景),要么放弃互斥锁,以便其他线程\进程等待该互斥锁并抛出 AbandonedMutexException。所以应该是:

using (Mutex mutex = new Mutex(true, "Global\\AAA", out createdNew)) {
if (!createdNew) {
throw new InvalidOperationException();
}
// do something useful
mutex.ReleaseMutex();
}

第二次使用也不正确:

Mutex mutex = new Mutex(false, "Global\\AAA", out createdNew)

通过将 false 作为您说的第一个参数传递:此互斥量是否已存在 - 不要将其所有权授予此线程。然后你做:

if (!createdNew)
{
mutex.ReleaseMutex();
}

但是此时您无论如何都不能拥有互斥量,因此即使控制流进入此 if block - 它也不会工作(在 ReleaseMutex 上抛出异常)。相反,您应该显式调用 WaitOne 并忽略 createdNew 的结果(在这种情况下不相关):

using (Mutex mutex = new Mutex(false, "Global\\AAA")) {
if (mutex.WaitOne()) {
// do something useful
mutex.ReleaseMutex();
}
}

关于c# - 如果我在以下代码中重用现有的 Mutex,为什么会得到一个新创建的 Mutex?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47570636/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com