.net 中引发事件时出现死锁

发布于 2024-11-26 23:18:20 字数 943 浏览 8 评论 0原文

我遇到了奇怪的僵局情况。附设视觉工作室后。我看到 3 个线程卡住了。

  1. 主题 1:

    if (SomeEvent != null)
       SomeEvent(this, new SomeArg) -->;卡住
    
  2. 线程 2:

    if (SomeEvent2 != null)
        SomeEvent2(this, new SomeArg2) -->;卡住
    
  3. 主线程:

    公共对象(委托方法,object[] args)
    {
       ...
       SynchronizationContext.Send(委托(对象状态))
       {
           ...
           方法.DynamicInvoke(args); -->卡住
       }
    }
    

这三个线程被卡住了,当我检查它们的调用堆栈时,我找不到任何共享资源,例如 lock() 或 <代码>Monitor.Wait()。我相信他们都被外部电话困住了。

此外,我无法判断 method.DynamicInvoke(args) 正在做什么以及该方法应该是什么。

我发现的唯一一件事是附加的事件处理程序可能会导致死锁。然而,由于 VS 已经向我展示了这是它卡住的地方,而不是事件处理程序代码。我想可能是别的东西。

就应用程序而言,我知道这是一个竞争条件,因为应用程序试图大约在同一时间执行加载和卸载数据,所以这个问题很难重现。

我的问题是:

  1. 为什么 .NET 线程在引发事件时会挂起,这有可能吗?
  2. 引发事件时是否需要使用主 UI 线程?
  3. 如果事件确实有可能陷入僵局,我应该如何防止这种情况发生?

谢谢

I have a weird deadlock situation. After attached visual studio. I saw 3 threads that stuck.

  1. Thread 1:

    if (SomeEvent != null)
       SomeEvent(this, new SomeArg) --> Stuck
    
  2. Thread 2:

    if (SomeEvent2 != null)
        SomeEvent2(this, new SomeArg2) --> Stuck
    
  3. Main Thread:

    public object (Delegate method, object[] args)
    {
       ...
       SynchronizationContext.Send(delegate(object state))
       {
           ...
           method.DynamicInvoke(args); --> Stuck
       }
    }
    

These three threads are stuck, and when I check their call stacks, I wasn't able to find any shared resource, like lock(), or Monitor.Wait(). I believe they all stuck on external calls.

In addition, I can't tell what method.DynamicInvoke(args) is doing and what this method supposed to be.

The only one thing I found is that the attached event handlers may cause deadlock. However, since VS has show me this is where it stucks, and not at the event handler code. I think it may be something else.

In term of the application, I know this is a race condition, because the application was trying to perform loading and unload data around the same time, so this problem is rather hard to reproduce.

My question are:

  1. Why would .NET thread hangs when raising an event, is it even possible?
  2. Does the Main UI thread need to be used when raising an event?
  3. If indeed it is possible for the event raising to deadlock, how should I prevent this?

Thanks

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

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

发布评论

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

评论(1

动听の歌 2024-12-03 23:18:20
  1. 引发事件时线程是否可能挂起?是的。在事件处理程序完成之前,执行线程不会从事件的引发中返回。事件处理程序可以是任何东西,因此它们可以挂起。如果事件处理程序挂起,则引发事件的线程也会挂起。

  2. 不,主 UI 线程不需要用于引发事件。任何线程都可以引发事件。

  3. 事件引发并不是特别容易出现死锁,但它也不能幸免。当您引发事件时,您所在的线程将执行已注册为事件处理程序的任何代码。该代码并不特殊。它只是在引发事件的同一线程上执行的代码。它可能会死锁,也可能不会死锁,原因与任何代码都可能死锁的原因相同。

关键是事件和事件处理程序的代码如何执行并没有什么特别神奇的地方。虽然我简化到几乎肯定是错误的,但基本原理是事件只是多播委托,可将元素公开添加到其调用列表或从其调用列表中删除,但所有其他形式的访问都是私有的。没有任何与线程相关的事件。与以其他方式在事件处理程序中执行相同的代码相比,使用事件不会影响死锁的存在。

  1. Is it possible for a thread to hang when raising an event? Yes, it is. The thread of execution doesn't return from the raising of the event until the event handlers are finished. Event handlers could be anything, and therefore they can hang. If an event handler hangs, the event-raising thread hangs.

  2. No, the Main UI thread does not need to be used to raise events. Any thread can raise events.

  3. Event raising isn't especially prone to deadlocks, but it isn't immune to it either. When you raise an event the thread you are on executes whatever code has been registered as event handlers. That code isn't special. It's just code executing on the same thread that raised the event. It can deadlock or not for all the same reasons any code can deadlock.

The point is that there isn't anything particularly magical about how the code for events and event handlers gets executed. While I'm simplifying to the point that I'm almost certainly wrong, the basics are that events are just multicast delegates that are available to have elements added to and removed from their invocation list publicly, but all other forms access are private. There is nothing about events that is thread related. Using events wouldn't impact the existence of a deadlock as compared to executing the same code in the event handlers some other way.

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