2015-11-23 58 views
0

我想填補知識空白。我有一個控件調用BeginInvoke(委託),然後控件立即自行處置。爲什麼控件的BeginInvoke()目標委託永遠不會發生在控件上調用Dispose()之後?

委託從未出現過。這似乎是Control.Dispose()的結果。

我的困惑在於(我認爲)BeginInvoke將委託放置到稍後在UI線程上處理的Windows消息隊列中。爲什麼處置這個控制與這個代表不再發射有關?它在處置之前已經放在隊列中。另外,如果它與Windows句柄有關,爲什麼我不會得到一個異常而不是安靜地忽略委託?下面

是我的意思一個簡單的例子:

class myControl : UserControl 
{ 
    public myControl() 
     : base() 
    { } 

    public void DoBeginInvoke() 
    { 
     this.BeginInvoke(new MethodInvoker(
      () => { Console.WriteLine("!!TESTING 123!!"); } 
     )); 

     // silently prevents the delegate from occuring.. 
     this.Dispose(); 
    } 
} 

預先感謝你的解釋。爲簡單問題道歉。

+0

你確信對象沒有之前被調用的方法設置?應該立即執行Dispose調用,而BeginInvoke會在稍後排隊。 –

+0

這是非常有意的,Control.Dispose()通過調用隊列並刪除所有未決的調用。如果不這樣做,那麼程序很可能會以非常難以診斷的方式轟炸ObjectDisposedException。它只是一種創可貼,而不是一個真正的解決方案,它使得您的bug更易於診斷。在UI消失後讓線程繼續調用是一個非常常見的錯誤。 –

+0

謝謝Hans Passant。這個解釋爲我增加了寶貴的額外洞察力。 – n00bCoder

回答

1

據我所知,BeginInvoke的是作爲一個PostMessage的實施,以及處置將調用DestroyWindow上窗把手 檢查this answer和有關的DestroyWindow鏈接的MSDN頁:它說,它

刷新線程消息隊列。

因此,這意味着你的BeginInvoke也會被刷新

+0

謝謝,這正是我需要聽到的。衝突的消息隊列處置顯然是我不明白的差距。 – n00bCoder

相關問題