サーチ…


Control.Invoke()を使用してスレッドセーフな呼び出しを実行する

Control.Invoke()メソッドを使用すると、メソッドまたは関数の実行をバックグラウンドスレッドから、コントロールが作成されたスレッド(通常はUI(ユーザーインターフェイス)スレッド)に移動できます。これにより、コードはコントロールのスレッド上で実行されるようにキューに入れられ、同時実行の可能性がなくなります。

呼び出す必要があるかどうか、またはコードが既にコントロールと同じスレッドで実行されているかどうかを判断するには、 Control.InvokeRequiredプロパティもチェックする必要があります。

Invoke()メソッドは、その最初のパラメータとしてデリゲートをとります。デリゲートは、参照、パラメータリスト、および戻り値の型を別のメソッドに保持します。

Visual Basic 2010(10.0)以降では、 ラムダ式を使用して、その場でデリゲートメソッドを作成できます。

If LogTextBox.InvokeRequired = True Then
    LogTextBox.Invoke(Sub() LogTextBox.AppendText("Check passed"))
Else
    LogTextBox.AppendText("Check passed")
End If

Visual Basic 2008(9.0)以下では、独自にデリゲートを宣言する必要があります。

Delegate Sub AddLogText(ByVal Text As String)

If LogTextBox.InvokeRequired = True Then
    LogTextBox.Invoke(New AddLogText(AddressOf UpdateLog), "Check passed")
Else
    UpdateLog("Check passed")
End If

Sub UpdateLog(ByVal Text As String)
    LogTextBox.AppendText(Text)
End Sub

Async / Awaitを使用してスレッドセーフな呼び出しを実行する

UIスレッドのオブジェクトを別のスレッドから変更しようとすると、クロススレッド操作の例外が発生します。

Private Sub Button_Click(sender As Object, e As EventArgs) Handles MyButton.Click
    ' Cross thread-operation exception as the assignment is executed on a different thread
    ' from the UI one:
    Task.Run(Sub() MyButton.Text = Thread.CurrentThread.ManagedThreadId)
End Sub

VB 14.0.NET 4.5の前に、ソリューションはUIスレッド上の割り当てとオブジェクトの呼び出しを呼び出していました。

Private Sub Button_Click(sender As Object, e As EventArgs) Handles MyButton.Click
    ' This will run the conde on the UI thread:
    MyButton.Invoke(Sub() MyButton.Text = Thread.CurrentThread.ManagedThreadId)
End Sub

VB 14.0では、別のスレッドでTaskを実行し、実行が完了するとコンテキストを復元して、Async / Awaitで割り当てを実行できます。

Private Async Sub Button_Click(sender As Object, e As EventArgs) Handles MyButton.Click
    ' This will run the code on a different thread then the context is restored
    ' so the assignment happens on the UI thread:
    MyButton.Text = Await Task.Run(Function() Thread.CurrentThread.ManagedThreadId)
End Sub


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow