2013-01-16 69 views
1

我的VB.Net應用程序出現了一個奇怪的掛起問題。當用戶點擊更新按鈕時,下面的代碼將作爲一個線程運行,以對數據進行一些長時間的計算。它禁用該控件,顯示「正在工作...」文本框,完成該工作,重新啓用控件並擺脫「正在工作...」文本框。 Occasionaly(我從來沒有在調試時複製),用戶窗口凍結並掛起。當它發生時,CPU使用率爲0,因此它完成了計算,但控件仍顯示爲禁用,並且「正在工作...」文本框仍然可見,但該窗口完全卡住且不會更新。這將無限期保持這種方式(用戶試圖等待長達30分鐘)。奇怪的是,我只能通過點擊任務欄窗口右鍵菜單中的最小化/恢復按鈕來「解開」窗口。經過短暫的延遲,窗戶就會恢復生機。窗口本身的最小化/恢復似乎沒有效果。運行線程時,窗口偶爾掛起/死機

所以我的問題,我在我的下面的線程中做錯了什麼?

Dim Thread As New Threading.Thread(AddressOf SubDoPriceUpdateThread) 
Thread.Start() 

主題:

Private Sub SubDoPriceUpdateThread() 

      Dim Loading As New TextBox 
      Try 
       CntQuotePriceSummary1.Invoke(New Action(Of Control)(AddressOf CntQuotePriceSummary1.Controls.Add), Loading) 
       CntQuotePriceSummary1.Invoke(New Action(Sub() CntQuotePriceSummary1.Enabled = False)) 

       Loading.Invoke(New Action(AddressOf Loading.BringToFront)) 
       Loading.Invoke(New Action(Sub() Loading.Text = "Working...")) 

       '***Long running calculations*** 

       Invoke(New Action(AddressOf FillForm)) 

      Finally 
       CntQuotePriceSummary1.Invoke(New Action(Of Control)(AddressOf CntQuotePriceSummary1.Controls.Remove), Loading) 
       CntQuotePriceSummary1.Invoke(New Action(Sub() CntQuotePriceSummary1.Enabled = True)) 
       Loading.Invoke(New Action(AddressOf Loading.Dispose)) 
      End Try 

    End Sub 
+0

如果Loading是表單的名稱,那麼它的Invoke()方法實際上不會調用到UI線程。違反線程要求並容易導致死鎖。請參見http://stackoverflow.com/a/14287947/17034 –

+0

@HansPassant,Loading是一個文本框,在該函數的頂部創建,僅用於在控件頂部顯示一個簡單的「工作」文本,該文本顯示總計用戶清爽。它被添加到頂部的'CntQuotePriceSummary',然後被移除並在'Finally'塊中處理。 – Kratz

+0

由於新的TextBox無法工作。您必須使用在UI線程上創建的現有控件。這是它能夠找出哪個線程需要被調用的唯一方式。如果你的代碼片段是準確的,那麼Me.Invoke()就可以工作。 –

回答

0

每漢斯的意見,其明確指出,Loading文本框是不是在UI線程上創建的,這就是將已經導致死鎖問題。我已經重寫了代碼。

 Private Sub SubDoPriceUpdateThread() 

      Dim Loading As TextBox 
      Invoke(Sub() Loading = New TextBox) 

      Try 
       Invoke(Sub() 
          CntQuotePriceSummary1.Controls.Add(Loading) 
          CntQuotePriceSummary1.Enabled = False 
          Loading.BringToFront() 
          Loading.Text = "Working..." 
         End Sub) 

       '***Long running calculations*** 

       Invoke(Sub() FillForm()) 

      Finally 
       Invoke(Sub() 
          CntQuotePriceSummary1.Controls.Remove(Loading) 
          CntQuotePriceSummary1.Enabled = True 
          Loading.Hide() 
          Loading.Dispose() 
         End Sub) 
      End Try 

    End Sub