从未同步的代码块调用对象同步方法

发布于 2024-12-07 11:09:38 字数 409 浏览 0 评论 0原文

我在生产中收到异常消息“对象同步方法是从不同步的代码块调用的”,Mutex.ReleaseMutex() 的代码如下:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}
[NonSerialized]
Mutex mutex;

public void Log(/*...*/)
{
    Mutex.WaitOne();
    try
    {
        /*...*/
    }
    finally
    {
        Mutex.ReleaseMutex();
    }
}

可能存在可以使用具有不同和相同 mutextName 的互斥体的保存进程。 我仍然不确定这种异常是如何发生的。

I receive an exception in production with message "Object synchronization method was called from an unsynchronized block of code" on Mutex.ReleaseMutex() in following code:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}
[NonSerialized]
Mutex mutex;

public void Log(/*...*/)
{
    Mutex.WaitOne();
    try
    {
        /*...*/
    }
    finally
    {
        Mutex.ReleaseMutex();
    }
}

There may be saveral processes which can use mutexes with different and same mutextName.
And still I am not sure how that exception can happen there.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千仐 2024-12-14 11:09:38

这段代码:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}

这不是线程安全的,可能会创建多个互斥锁。使用假装时间,让我们看一下这个例子:

Thread A        |  Thread B
-------------------------------------
Enters
Is Null? (yes)   Enters
Create Mutex     Is Null? (yes) <- Thread A hasn't assigned it yet.
Assign mutex     Create Mutex
Use Mutex        Assign mutex  <- Oops! We just overwrote the mutex thread A created!
Release Mutex <- Oops! We are trying to release the mutex Thread B created without owning it!

希望这个插图不是垃圾。

如果您确实想对互斥体执行此操作,则使用 System.Lazy类是执行延迟初始化的线程安全方法。

private Lazy<Mutex> _lazyMutex = new Lazy<Mutex>(() => new Mutex(false, "MyMutex"));
Mutex Mutex
{
    get { return _lazyMutex.Value; }
}

鉴于此,您为什么要尝试延迟初始化互斥体?你如何处置它?

This code:

Mutex Mutex
{
    get { return mutex ?? (mutex = new Mutex(false, mutexName)); }
}

That is not thread safe, more than one Mutex may get created. Using pretend time, let's look at this example:

Thread A        |  Thread B
-------------------------------------
Enters
Is Null? (yes)   Enters
Create Mutex     Is Null? (yes) <- Thread A hasn't assigned it yet.
Assign mutex     Create Mutex
Use Mutex        Assign mutex  <- Oops! We just overwrote the mutex thread A created!
Release Mutex <- Oops! We are trying to release the mutex Thread B created without owning it!

Hopefully that illustration isn't garbage.

Using the System.Lazy<T> class is a thread-safe way of doing lazy initialization, if you really want to do that with your mutex.

private Lazy<Mutex> _lazyMutex = new Lazy<Mutex>(() => new Mutex(false, "MyMutex"));
Mutex Mutex
{
    get { return _lazyMutex.Value; }
}

Given that, why are you trying to lazy initialize your Mutex? How are you disposing of it?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文