2013-08-17 30 views
0

所以基本上我想我的應用程序運行一個相當cpu密集型的方法,同時它應該不斷地在不同的窗體上顯示狀態信息。爲了防止這種狀態凍結,我認爲將代碼外包給一個新線程是一個好主意。Vb.Net - 調用任務

首先,我嘗試使用基本線程並調用應顯示狀態消息的richtextbox控件。 - 問題是 - 我需要知道線程何時完成以繼續執行主線程。顯然,我不能簡單地在我的主線程中運行一個循環來檢查過程是否完成,因爲這會導致我的GUI凍結。

所以我做了一點研究,並發現了關於任務。 這是它的外觀:

Dim z as new complexProcessClass 
Dim taskA = task.Factory.StartNew(Sub() z.start()) 
taskA.Wait() 
If taskA.IsCompleted Then 
    MsgBox("finished") 
End If 

每當進程報告狀態我用這個:

Public Class complexProcessClass 
    dim statusWindow as statusForm 

    Public Sub start() 
    statusWindow = new statusForm 
    'complex code here 
    reportStatus("bla") 
    'complex code here 
    reportStatus("blabla") 
    'complex code here 
    End Sub 

    Private Delegate Sub UpdateTextHandler(ByVal Text As String) 
    Private Sub reportStatus(Byval s as String) 
    If z.RichTextBox1.InvokeRequired Then 
     Try 
     z.RichTextBox1.Invoke(New UpdateTextHandler(AddressOf xform.RichTextBox1.AppendText), s) 
     Catch ex As Exception 
       MsgBox(ex.ToString()) 
     End Try 

    Else 
     z.RichTextBox1.AppendText(s) 
    End If 
    End Sub 

,但它只是保持凍結的invoke調用 - 沒有錯誤信息 - 什麼?

任何人都可以告訴我正確的方法來做到這一點? - 和請沒有BackgroundWorker的解決方案;)

在此先感謝

回答

0

看看在BackgroundWorker類。這post應該讓你開始。

另一種方法是創建委託並異步調用線程並實現更新函數以捕獲工作完成時的情況。

  1. 與工作代碼作爲函數
  2. 在類中創建/添加委託函數處理程序
  3. 內,您的形式的頂部創建一個類處理程序添加到新類調用你的類方法。
  4. 創建一個回調處理程序方法以接收執行導出功能的線程的狀態。讓callbackhandler調用更新UI函數,檢查線程是從UI運行還是另一個線程。 (Me.InvokeRequired支票本)

  5. 裏面的表格BTN點擊事件的調用使用 的targetHandler調用的方法。

下面的代碼是表單代碼的樣子。


    Public Class Form1 
    Private targetHandler As ClassName.Handler = AddressOf objNewClass.somework

Private callbackHandler As AsyncCallback _ = AddressOf MyCallbackMethod Sub MyCallbackMethod(ByVal ar As IAsyncResult) '*** this code fires at completion of each asynchronous method call Try Dim retval As Boolean = targetHandler.EndInvoke(ar) If retval = True Then Console.Write(retval) End If UpdateUI("Task complete") Catch ex As Exception Dim msg As String msg = "Error: " & ex.Message UpdateUI(msg) End Try End Sub Sub UpdateUI(ByVal statusMessage As String) If Me.InvokeRequired Then Dim handler As New UpdateUIHandler(AddressOf UpdateUI_Impl) Dim args() As Object = {statusMessage} Me.BeginInvoke(handler, args) Else UpdateUI_Impl(statusMessage) End If End Sub Delegate Sub UpdateUIHandler(ByVal statusMessage As String) Sub UpdateUI_Impl(ByVal statusMessage As String) Me.sbMain.Panels("Status").Text = statusMessage End Sub 'Call to your worker thread Private Sub btn_Click() Handles Button1.Click Dim result As IAsyncResult =targetHandler.BeginInvoke(callbackHandler,Nothing) End Sub End Class
0

你必須在那裏taskA.Wait()阻塞UI線程死鎖情況,以及Invoke()調用內部taskA正在等待UI線程完成它在做什麼。正在等待,直到完成等待。哪個永遠不會。

我不能完全肯定,但試試這個:

Dim taskA = task.Factory.StartNew(Sub() z.start()).ConfigureAwait(False)