0

したがって、基本的には、アプリケーションで CPU を大量に使用するメソッドを実行する必要があり、その間、別のフォームにステータス情報を常に表示する必要があります。このステータス フォームがフリーズするのを防ぐために、コードを新しいスレッドに外部委託することをお勧めします。

最初に、基本的なスレッド化を使用して、ステータス メッセージを表示するリッチテキスト ボックス コントロールを呼び出してみました。- 問題は - メインスレッドを続行するには、スレッドがいつ終了するかを知る必要があります。明らかに、プロセスが終了したかどうかをチェックし続けるメインスレッドで単純にループを実行することはできません。これにより、GUI もフリーズします。

そこで、少し調べてみて、Tasks について知りました。それがどのように見えるかです:

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

しかし、呼び出し時にフリーズし続けるだけです-エラーメッセージはありません-何もありません?!

誰でもこれを行う正しい方法を教えてもらえますか? -そして、バックグラウンドワーカーの解決策はありません;)

前もって感謝します

4

2 に答える 2

0

taskA.Wait()がUI スレッドをブロックしているデッドロック状況があり、Invoke()内部の呼び出しtaskAは UI スレッドが処理を完了するのを待っています。それが完了するまで待っているのは待っています。これは決してありません。

完全にはわかりませんが、これを試してください:

Dim taskA = task.Factory.StartNew(Sub() z.start()).ConfigureAwait(False)
于 2013-08-17T22:02:10.690 に答える
0

BackgroundWorkerクラスを見てください。この投稿から始める必要があります。

もう 1 つの方法は、デリゲートを作成し、スレッドを非同期的に呼び出し、更新関数を実装して、作業が完了したときにキャッチすることです。

  1. 作業コードを関数としてクラスを作成する
  2. クラスの先頭にデリゲート関数ハンドラを作成/追加します
  3. フォーム内で、クラス メソッドへの呼び出しを使用して新しいクラスにハンドラーを追加します。
  4. エクスポート機能を実行しているスレッドのステータスを受け取るコールバック ハンドラ メソッドを作成します。スレッドが UI から実行されているか、別のスレッドであるかをチェックする update ui 関数をコールバック ハンドラに呼び出します。(Me.InvokeRequired がこれをチェックします)

  5. Form btn click イベント内で、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
于 2013-08-17T18:39:51.490 に答える