c# - 重写 C# 的 Monitor.Enter 和 Monitor.Exit

标签 c# multithreading operator-overloading overriding deadlock

我正在开发一些大型多线程项目,昨天我遇到了死锁(我的第一个死锁),我通过添加 Console.WriteLine("FunctionName: Lock on VariableName") 和 Console.WriteLine 来跟踪它(“函数名:解锁变量名”)。添加所有这些是一项相当大的工作。

首先,该程序有一个每秒运行 2 次的主循环,该循环在主循环处理后向其他线程发出脉冲以完成其工作。现在发生的事情是,我有一个处于等待状态的线程要发出脉冲,当它发出脉冲时,它调用另一种方法,该方法也会等待发出脉冲,但脉冲已经发生,并且线程不会再次发出脉冲,直到该操作实际完成了。

现在我想做的是重写 Monitor.Enter 和 Monitor.Exit 函数,而不将它们包装在类中。
我听说过很多关于反射的内容,但我不知道如何将其应用于此目的,我知道实现这一切的最简单方法是仅使用包装类,但随后 lock 关键字将不再起作用,我必须将所有锁转换为 Monitor.Enter try { } finally { Monitor.Exit },这是一项巨大的工作量。

所以我的问题:如何重写 Monitor.Enter 和 Monitor.Exit 函数,同时保持对基本函数的访问以进行实际锁定?
如果这是不可能的:如何重写锁定语句来调用我的包装类而不是 Monitor.Enter 和 Monitor.Exit 函数?

为了清晰起见进行编辑:
我请求这个只是为了允许我在锁定发生时记录,以使调试过程更容易,这也意味着我不想创建自己的锁定机制,我只想在锁定建立时记录/em> 以及何时发布
大多数情况下,只有当我遇到线程问题时,关闭也不会执行。

最佳答案

听起来您正在寻找锁定助手。 Jon Skeet 的 MiscUtil 有一些: http://www.yoda.arachsys.com/csharp/miscutil/usage/locking.html

这个想法是用 using 语句替换 lock 语句,从而保留 try-finally 结构:

class Example
{
    SyncLock padlock = new SyncLock();

    void Method1
    {
        using (padlock.Lock())
        {
            // Now own the padlock
        }
    }      

    void Method2
    {
        using (padlock.Lock())
        {
            // Now own the padlock
        }
    }
}

关于死锁预防,库提供了专门的有序锁:

class Example
{
    OrderedLock inner = new OrderedLock("Inner");
    OrderedLock outer = new OrderedLock("Outer");

    Example()
    {
        outer.InnerLock = inner;
    }
}

当然,您可以扩展 Jon 的助手,或者简单地创建您自己的助手(用于日志记录目的等)。查看上面的链接以获取更多信息。

关于c# - 重写 C# 的 Monitor.Enter 和 Monitor.Exit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5078030/

相关文章:

multithreading - 多个读者同步,单个作者?

c++ - 重载运算符以合并 vector

c++ - 如何在 C++ Gtest 中测试输入和输出重载运算符

c# - WHILE 循环中的 ListView.FindItemWithText 在第一个 ListView 行后失败

java - 访问java中的同步方法

c# - Windows 应用程序中的异常处理 C#

c# - ASP.NET/C# 事件差异

c++:运算符重载和错误处理

c# - 使用 Microsoft.Graph API 检索 ItemAttachment

c# - 如何转换为 List<IEnumerable<XElement>>