UIは元よりUXは尚更、快適な操作環境を云々、と叫ばれてから早十余年。タッチ操作が主流?となった今では、当然の如き言われ様。
でもね、フリーズしてる訳でもないんだし、プログレスバーでも出しておけば良いんじゃないの?と思ってしまうのはさて置き。
色々検索してみると、即応性=非同期 ⇒ コールバック ⇔ デリゲート が良いらしい(単なるマイクロソフトの推奨?)って事で、
以前、C言語でデリゲートとイベントの概要記事「VC++フォームだからこそ、コマンドプロンプトでEXE?」を書きましたので、それを眺めつつ先ずは、Delegateの使い方を浚ってみる事に。
マイクロソフトのドキュメントによると、
デリゲートは、メソッドを参照するオブジェクトです。デリゲートは他のプログラミング言語で使用される関数ポインターに似ているため、"タイプセーフ関数ポインター"と説明されることがあります。しかしながら、関数ポインターとは異なり、Visual Basicのデリゲートは、System.Delegateクラスに基づく参照型です。
と、何とも要領の得ない、教えたくない様な説明。きっと独自では使って欲しくないのでしょうね。
マイクロソフトのドキュメントによれば、Delegateの構文は、
[<attrlist>][accessmodifier][Shadows] Delegate [Sub | Function] name [(Of typeparamlist)][([parameterlist])][As type]
なので、敢えて大雑把に言ってしまえば以下の様な形式かと。
Delegate Sub デリゲート名称(仮引数リスト...)
または
Delegate Function デリゲート名称(仮引数リスト...) As 戻り値の型
★さて、デリゲートとは?と問われれば一種の型です。利用するためのポイントは以下の5つで、
①デリゲートの宣言(メソッドのシグネチャを定義)
②デリゲートで呼び出すメソッドの作成
③デリゲート型の変数を宣言
④デリゲート型変数にメソッドを登録
⑤デリゲートの呼出し
となるようです。
<注意点>
・デリゲートの機能の一つは、メソッドのアドレスを格納する変数の宣言と呼び出すメソッドを登録出来る型。
・メソッドのシグネチャは同一である事が重要。引数の数と型、戻り値の型が同じ。
・通常のデリゲートの呼出しは同期して行われる(同一スレッド)ので、メソッドの処理が完了してから呼び出し元スレッドに制御が戻る。今回の場合、メッセージボックスのタイトルは「Delegate Method」「Delegate Test」の順で表示される。
お試し環境
Windows7 64bit Edition
Visual Basic 2008 AnyCPU対象
/*-------------------------------- お試し結果 ------------------------------*/
・ボタン1を押すと、約2秒後に表示
・上記画面のOKボタンを押すと、直ぐに表示
・ボタン1を押すと、約2秒後にラベルのテキストを表示
/*----------------------------------------------------------------------------*/
/*---------------------------- お試しソース -------------------------------*/
Public Class Form3
Delegate Sub dlgtDispMsg(ByVal msg As String) ' ①デリゲートの定義
Private Sub DisplayMsg(ByVal msg As String) ' ②デリゲートで呼び出すメソッドの作成
System.Threading.Thread.Sleep(2000)
Label1.Text = "Delegate Method" & " and " & msg
MsgBox(msg, MsgBoxStyle.Information, "Delegate Method")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim dispMsg As dlgtDispMsg ' ③デリゲート型の変数を宣言
dispMsg = New dlgtDispMsg(AddressOf DisplayMsg) ' ④デリゲート型変数にメソッドを登録
dispMsg("See actions") ' ⑤デリゲートの呼び出し
MsgBox("See actions", MsgBoxStyle.Information, "Delegate Test")
End Sub
End Class
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*============================================================================*/