VisualBasicでもDelegate処理-別スレッドからUI更新のお浚い

|

前回の非同期処理では、別スレッドからUIコントロールの Label1.Text 更新が出来ませんでしたので、別スレッドからUIコントロール更新の仕方を浚ってみる事に。

別スレッドで実行しているメソッドがUIを書き換える場合、処理をUIスレッドに移行する必要が有りますが、それにはWindowsフォームが備えているInvokeメソッドを呼び出すと良い様です。

尚、別スレッドで実行されると分かっているなら、直接Invokeメソッドを呼び出した方が簡単なのですが、後の改修などを考慮してInvokeRequiredプロパティを使用するのが定石?なんだそうです。


<注意点>

・InvokeRequiredプロパティは、UIスレッドと異なるスレッドで実行していると"真"を返します。

・分かり易い?様に敢えて、別スレッドからUIを更新する為のデリゲートを定義していますが、(関数呼び出しとは違い)デリゲートの名称は区別されず、同一のシグネチャが重要なので、「Invoke(New dlgtShowMsg(AddressOf SetLabel1Text), ・・・)」でも構いません。


お試し環境
  Windows7 64bit Edition
  Visual Basic 2008 AnyCPU対象


/*-------------------------------- お試し結果 ------------------------------*/

・メッセージボックスの表示は、前回と同じなので省略

・ボタン3を押すと、約2秒後にラベルのテキストを表示

ラベルの更新テキストを表示

/*----------------------------------------------------------------------------*/


/*----------------------------  お試しソース -------------------------------*/

Public Class Form3

    Delegate Sub dlgtShowMsg(ByVal msg As String)

    Private Sub ShowMessage(ByVal msg As String) ' BeginInvokeから呼ばれるので別スレッド
        System.Threading.Thread.Sleep(2000)
        Invoke(New dlgtSetLabel1(AddressOf SetLabel1Text), "Asynchronous Method" & " and " & msg) ' 別スレッドからUIを更新するInvoke呼出し
        MsgBox(msg, MsgBoxStyle.Information, "Asynchronous Method")
    End Sub

    Private Sub showCallback(ByVal ar As IAsyncResult) ' コールバックメソッド
        Dim arShowMsg As dlgtShowMsg

        arShowMsg = CType(ar.AsyncState, dlgtShowMsg)
        arShowMsg.EndInvoke(ar)
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim showMsg As dlgtShowMsg
        Dim ar As IAsyncResult

        showMsg = New dlgtShowMsg(AddressOf ShowMessage)
        ar = showMsg.BeginInvoke("See actions", New AsyncCallback(AddressOf showCallback), showMsg)

        MsgBox("See actions", MsgBoxStyle.Information, "Asynchronous Test")
    End Sub

    Delegate Sub dlgtSetLabel1(ByVal msg As String) ' ①別スレッドからUIを更新するデリゲートの定義

    Private Sub SetLabel1Text(ByVal msg As String) ' ②別スレッドからUIを更新するメソッドの作成
        If InvokeRequired = True Then ' ③Windowsフォームは別スレッドからのUI操作は保障されていない
            Invoke(New dlgtSetLabel1(AddressOf SetLabel1Text), "Required " & msg)
        Else
            Label1.Text = msg
        End If
    End Sub

End Class

/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/*============================================================================*/

このブログ記事について

このページは、微禄が2022年4月30日 07:23に書いたブログ記事です。

ひとつ前のブログ記事は「VisualBasicでもDelegate処理-非同期処理のお浚い」です。

次のブログ記事は「VisualBasicでもDelegate処理-プログレスバーでも出しておけば」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

お気に入りリンク

NOP法人 アジアチャイルドサポート 最も大切なボランティアは、自分自身が一生懸命に生きること