簡體   English   中英

從調用內部關閉表格

[英]Closing Form from inside an Invoke

從這樣的Invoke內部關閉表單:

Invoke(new Action(() => {
    Close();
    MessageBox.Show("closed in invoke from another thread");
    new Form1();
}));

關閉表單后立即引發異常:

在創建窗口句柄之前,無法在控件上調用Invoke或BeginInvoke。

但僅在NET 4.0上。 在NET 4.5上,不會引發任何異常。

這是預期的行為嗎? 我應該怎么做?

如果在初始化期間啟動線程,則不知道初始化在另一個線程中進行了多長時間。

您會注意到不同.Net版本在行為上的差異,但是您無法確定不同計算機上事物的順序。

我已經使用自己的messagepump,隊列和常規Timer控件解決了Windows窗體中的許多線程問題:

  • 將計時器控件添加到窗體中,間隔很小(250毫秒)
  • 將隊列添加到您的窗體。
  • 讓timer事件使動作出隊並執行它。
  • 在初始化甚至其他后台作業期間將操作添加到隊列中。

使用此方法將在初始化期間以及在關閉/處置表單期間給后台作業帶來問題,因為計時器僅在表單完全起作用時才會觸發。

這是因為Close方法關閉了窗體並破壞了它的句柄,然后在沒有句柄的Closed窗體中調用了MessageBox,因此顯示了錯誤消息。

我不明白您的目的,但是您應該在“關閉”之后將代碼移出調用,或者將“關閉”移到它們之后。 例如:

Invoke(new Action(() => {
    Hide();
    MessageBox.Show("closed in invoke from another thread");
    new Form1();
    Close();
}));

編輯:

有關Control.Invoke的 MSDN注意:

如果當前控件的基礎窗口句柄尚不存在,則Invoke方法將向上搜索控件的父鏈,直到找到具有窗口句柄的控件或窗體。 如果找不到合適的句柄,則Invoke方法將引發異常。 呼叫期間引發的異常將傳播回呼叫者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM