我有一個奇怪的死鎖情況。附加視覺工作室後。我看到3個線程卡住了。在.net中發生事件的僵局
線程1:
if (SomeEvent != null) SomeEvent(this, new SomeArg) --> Stuck
線程2:
if (SomeEvent2 != null) SomeEvent2(this, new SomeArg2) --> Stuck
主線:
public object (Delegate method, object[] args) { ... SynchronizationContext.Send(delegate(object state)) { ... method.DynamicInvoke(args); --> Stuck } }
這三個線程都卡住了,當我檢查它們的調用堆棧時,我無法找到任何共享資源,如lock()
或Monitor.Wait()
。我相信他們都堅持打外線電話。
此外,我不知道什麼method.DynamicInvoke(args)
正在做什麼,這種方法應該是什麼。
我發現的唯一一件事是附加的事件處理程序可能會導致死鎖。然而,由於VS已經告訴我這是它的位置,而不是事件處理程序的代碼。我認爲這可能是別的。
就應用程序而言,我知道這是一個競爭條件,因爲應用程序試圖在同一時間執行加載和卸載數據,所以這個問題很難重現。
我的問題是:
- 爲什麼.NET引發一個事件時危在旦夕,是它甚至可能嗎?
- 舉辦活動時是否需要使用主UI線程?
- 如果確實有可能導致事件發生僵局,我應該如何防止這種情況發生?
感謝
爲了您的第一條評論,VS堆棧顯示籌集活動卡在外部電話。我認爲外部通話意味着它不是託管代碼。通常我期望事件不會返回,因爲事件處理程序的代碼是死鎖。除非VS沒有以某種方式顯示完整的堆棧。另外,連接事件處理程序的方式通常是+ =,沒有任何自定義事件訂閱代碼。 – dsum
我的觀點只是事件與正常的代碼執行過程並沒有太大的不同,我將編輯我的答案以添加更多信息。通過外部呼叫,我假設你的意思是調用堆棧顯示'[External Code]'。外部代碼只是意味着Visual Studio不會將其視爲您的用戶代碼。您可以右鍵單擊調用堆棧窗口,然後從上下文菜單中選擇「顯示外部代碼」。當你這樣做時,你可能會看到一個'[Native to Managed Transition]',這是你離開託管代碼的地方。這可能會說明僵局的性質,或者不。 –