2012-06-23 29 views
0

根據對another question的回答,如果創建它的線程繁忙,則無法更新VB用戶界面:因此,爲什麼大型計算作業通常必須在後臺任務中執行。這個VB.net/COM dll的執行線程發生了什麼?

接下來是什麼讓人神往。我有以下代碼。這就是所謂的過度過程中的COM,這樣

  1. 客戶端調用showform()
  2. 客戶做的工作負載,在這個過程中
  3. 客戶端完成工作,凍結了自己的UI,返回到更新自己的UI

在第2步,VB窗體在那裏但凍結 - 你不能與它交互。在步驟3,VB表單變爲可用。但爲什麼呢?執行的線程當然已經返回給客戶端了嗎?如果客戶以某種方式處理表單的事件,通過什麼魔法知道要處理哪些事件以及將它們發送到哪裏?

<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _ 
Public Class ComClass1 

    Public Sub New() 
     MyBase.New() 
    End Sub 

    Private f1 As Form1 

    Public Sub showform() 
     f1 = New Form1() 
     f1.Show() 
    End Sub 

End Class 

回答

2

魔法您講的是Windows編程的基礎。我對前一個問題的回答解釋了爲什麼以及如何解決這個問題。在進行COM調用時,客戶端應用程序只需將您的過程導入其應用程序中。無論他們是通過自己鍵入代碼來創建表單還是使用您輸入的代碼創建表單都不會改變對象/所有者關係的性質。一個COM調用你的showForm仍然會使得f1屬於發起調用的線程(客戶端UI線程)。該窗口的窗口句柄仍然是創建它的UI線程(客戶端)的責任。

創建窗體只會生成一個郵箱(窗口句柄)。 UI線程是郵遞員(消息泵送循環)。你沒有爲客戶提供一個新的郵遞員,只是一個帶有郵箱的新對象。當客戶端程序通過對您的過程進行COM調用來創建窗口時,它(客戶端UI線程)負責將消息傳遞到新窗體的郵箱(使用主UI線程註冊它的窗口句柄)。他們的郵遞員仍然需要向你發送消息,以使你的視覺對象工作。如果他忙於將pi計算到萬億位數,那麼你的對象就像他郵件路由上的其他所有東西一樣凍結。

+0

哈哈,我喜歡通過計算pi分心的郵差分子的圖像:)所以,告訴我,如果這是正確的:客戶端線程有一個消息循環。 Form1包含調用Windows API並將客戶端線程註冊爲窗口負責的代碼。 Windows稍後決定Form1需要重新繪製,因此它將此請求添加到客戶端的消息隊列中。客戶得到這個消息,但它對它做了什麼?它是否會回調API,詢問實際重繪代碼的位置? –

+0

主UI線程(運行消息循環)將從Windows獲取「WM_PAINT」或某些此類消息。處理後,主線程將決定其監視下的哪些組件和控件需要重繪(即:哪些是可見的等),並設置調用所有這些「Paint」事件處理程序的任務組件。每一位都包含描述當需要繪畫時如何處理自己的代碼,但代碼由主UI線程響應來自Windows的消息執行。 –

0

檢查form.load事件。表單加載並運行代碼......這就是它凍結的地方。