当线程在到达锁定语句时等待时记录

时间:2011-10-12 15:27:14

标签: c# locking system.reactive task-parallel-library plinq

当线程到达

时,是否有一种快速记录线程正在等待锁定的方法
lock(x)
{
  //do work on a collection

}

如果线程1到达锁定,并且块中没有另一个线程,则应该没有日志。然后,如果线程2到达锁(x)并且线程1仍然在块中,则应该有一个日志。理想的解决方案不需要切换到互斥锁或监视器,这会增加复杂性。如果有一种快速简便的方法可以使用TPL,PLINQ或RX来做到这一点。

3 个答案:

答案 0 :(得分:9)

您可以de-sugar the lock statement并使用Monitor.TryEnter检查是否可以在不等待的情况下获取锁定:

bool lockTaken = false;
var obj = x;
try
{
    Monitor.TryEnter(obj, ref lockTaken);
    if (!lockTaken)
    {
        Log();
        Monitor.Enter(obj, ref lockTaken);
    }
    //do work on a collection
}
finally
{
    if (lockTaken)
    {
        Monitor.Exit(obj);
    }
}

答案 1 :(得分:2)

使用标准lock()语句,您无法轻松完成此操作。您可以使用Monitor.TryEnter()尝试输入锁定,然后在方法返回false时记录某些内容。

答案 2 :(得分:2)

你为什么要这样做?如果是用于调试或分析目的,则可以使用非托管CLR分析或调试API。另一个想法是在使用PostSharp或Afterthought等工具进行编译后静态修改您的IL代码。 (请注意,事后想法不能以当前形式执行此操作,但是如果您拥有源代码,则可以将其破解。)

我建议您修改代码。我推荐这个而不是dtb的语法:

if (!Monitor.TryEnter(x))
{
    Log();
    Monitor.Enter(x);
}
try
{
    //do work on a collection
}
finally
{
    Monitor.Exit(x);
}