在事件处理程序方法中使用 Monitor.TryEnter 可以吗?

发布于 2024-12-06 06:11:04 字数 309 浏览 1 评论 0原文

我有 EventHandler 方法,该方法经常被调用,并且它的主体处理需要一些时间。通过监视器锁定此处理程序内的操作可以吗? 目的是在locker锁定对象的同时,简单地跳过对象的其他事件和处理。

public void MyEventHandler(object sender, EventArgs e) 
{
if (!Monitor.TryEnter(locker)) return; // skipping meanwhile processing

// do some stuff here

Monitor.Exit(locker)
}

I have EventHandler method which is called pretty often and it's body processing takes some time. Is it OK, to lock operations inside this handler it via Monitor?
The purpose is that meanwhile locker locks the object other events and processing of the object are simply skipped.

public void MyEventHandler(object sender, EventArgs e) 
{
if (!Monitor.TryEnter(locker)) return; // skipping meanwhile processing

// do some stuff here

Monitor.Exit(locker)
}

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

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

发布评论

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

评论(2

烧了回忆取暖 2024-12-13 06:11:04

看起来

  • (a)防止引发事件
  • (b)使用条件变量会更干净/更高效。

无论如何,始终将 Monitor.Exit 放入 finally 块中

it looks like it would be cleaner/more performant to

  • (a) prevent the events from being raised
  • (b) use a condition variable.

Regardless, always put the Monitor.Exit into a finally block

握住我的手 2024-12-13 06:11:04

这并不可怕,只要:

  • 您在后台线程上执行此操作(或者,就这一点而言,您没有在事件处理线程上执行此操作)。
  • 您正在同步对 //do some stuff 代码所需的所有访问。
  • 您可以将 TryEnter 之后的所有内容包装在 try/finally 中,如下所示

public void MyEventHandler(object sender, EventArgs e)
{
    if (!Monitor.TryEnter(locker)) return;
    try
    {
        // do some stuff here
    }
    finally
    {
        Monitor.Exit(locker);
    }
}

(从而避免启动一个线程可能不执行任何操作 - 当然因为您没有在事件处理线程上进行这种耗时的处理...)

如果您可以完全阻止触发事件,那就更好了 ,如果您实际上不需要在整个持续时间内锁定(也就是说,如果事件处理程序不会执行任何需要与其他代码同步的操作),您可以锁定足够长的时间设置一个标志,例如

private Object condition_lock = new Object();
private bool handlingEvent = false;

public void MyEventHandler(object sender, EventArgs e)
{
    lock (condition_lock)
    {
        if (handlingEvent) return;
        handlingEvent = true;
    }
    try
    {
        // do some stuff here
    }
    finally
    {
        handlingEvent = false;
    }
}

It's not horrible, as long as:

  • You're doing this on a background thread (or, to the point, you're not doing this on the event handling thread).
  • You're synchronizing all access to whatever your //do some stuff code needs.
  • You wrap everything after the TryEnter in a try/finally, like so:

.

public void MyEventHandler(object sender, EventArgs e)
{
    if (!Monitor.TryEnter(locker)) return;
    try
    {
        // do some stuff here
    }
    finally
    {
        Monitor.Exit(locker);
    }
}

It'd be nicer if you could prevent firing the event at all (and thus avoid starting a thread to potentially do nothing -- cause of course you're not doing this time-consuming processing on the event handling thread...)

Alternatively, if you don't really need to lock for the whole duration (that is, if the event handler won't be doing anything that requires synchronization with other code), you could lock just long enough to set a flag, like

private Object condition_lock = new Object();
private bool handlingEvent = false;

public void MyEventHandler(object sender, EventArgs e)
{
    lock (condition_lock)
    {
        if (handlingEvent) return;
        handlingEvent = true;
    }
    try
    {
        // do some stuff here
    }
    finally
    {
        handlingEvent = false;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文