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

发布于 2024-12-09 14:44:45 字数 266 浏览 0 评论 0原文

当线程到达 a 时,是否有一种快速方法来记录线程正在等待锁

lock(x)
{
  //do work on a collection

}

如果线程 1 到达锁,并且块中没有其他线程,则不应有日志。那么如果线程2到达了lock(x),而线程1还在block中,就应该有日志。理想的解决方案不需要切换到互斥锁或监视器,从而增加太多复杂性。如果有一种快速、简单的方法可以使用 TPL、PLINQ 或 RX 来完成此操作,那就太好了。

Is there a quick way to log that a thread is waiting for a lock when a thread arrives at a

lock(x)
{
  //do work on a collection

}

?

If thread 1 arrives at the lock, and there isn't another thread in the block, there should be no log. Then if thread 2 arrives at the lock(x) and thread 1 is still in the block, there should be a log. The ideal solution would not require switching to a Mutex or Monitor add much complexity. If there's a quick and easy way to do this using TPL, PLINQ, or RX that would be great.

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

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

发布评论

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

评论(3

oО清风挽发oО 2024-12-16 14:44:45

您可以de -sugar lock 语句 并使用 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);
    }
}

You can de-sugar the lock statement and use Monitor.TryEnter to check if the lock can be acquired without waiting:

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);
    }
}
得不到的就毁灭 2024-12-16 14:44:45

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

You wouldn't be able to do this easily with the standard lock() statement. You can use Monitor.TryEnter() to attempt to enter the lock, and then log something if the method returns false.

∞琼窗梦回ˉ 2024-12-16 14:44:45

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

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

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

Why are you attempting to do this? If it is for debugging or profiling purposes, you could use the unmanaged CLR profiling or debugging API. Another thought would be to statically modify your IL code after compiling using a tool such as PostSharp or Afterthought. (Note that Afterthought cannot do this in its current form, but as you have the source you could hack this in.)

I would recommend that you modify your code instead. I'd recommend this instead of dtb's syntax:

if (!Monitor.TryEnter(x))
{
    Log();
    Monitor.Enter(x);
}
try
{
    //do work on a collection
}
finally
{
    Monitor.Exit(x);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文