非同期デリゲート処理の呼び出し完了待ちを検索していたら、マイクロソフトが言うには、
・呼び出すメソッドと同じシグネチャを持つデリゲートを定義すれば、.NETでは全てのメソッドを非同期的に呼び出すことが出来る。
・デリゲート定義では、共通言語ランタイム(CLR)により適切なシグネチャが使用された BeginInvoke および EndInvoke メソッドが自動的に定義される。
・BeginInvoke メソッドは、非同期的に実行するメソッドと同じパラメーターと、2つの省略可能な追加パラメーターを持っている。
追加の1つ目は、非同期呼び出しが完了したときに呼び出されるメソッドを参照する AsyncCallback デリゲート
追加の2つ目は、コールバックメソッドに情報を渡すユーザー定義オブジェクト。
・BeginInvoke は IAsyncResult を返すので、これを使用して非同期呼び出しの進捗状況を監視出来る。
・EndInvoke メソッドは、非同期処理の呼び出し結果を取得し、BeginInvoke の後であればいつでも呼び出すことが出来る。
・EndInvoke のパラメーターには、非同期実行するメソッドの <Out>ByRef と ByRef、BeginInvoke の戻り値 IAsyncResult が含まれる。
らしいので、追加パラメーター2つを省略して(=Nothing)、EndInvokeメソッドで非同期処理の終了待ちを試してみる事に(当然、UIスレッドには不向き)。
★元ネタ-マイクロソフトドキュメントで、ほぼそのままのソース。
<注意点>
・非同期呼び出しが完了していない場合、 EndInvoke は非同期呼び出しが完了するまで呼び出し元スレッドをブロック。
・エラー処理は手抜きです。
お試し環境
Windows7 64bit Edition
Visual Basic 2008 AnyCPU対象
/*-------------------------------- お試し結果 ------------------------------*/
Wait Test begins.
Button1 thread 10 does some work.
The call executed on thread 7, with return value "Wait time was 2000.".
/*----------------------------------------------------------------------------*/
/*---------------------------- お試しソース -------------------------------*/
Public Class Form1
Private Delegate Function dlgtAsyncWaitChk(ByVal tm As Integer, ByRef id As Integer) As String
Private Function waitTest(ByVal term As Integer, ByRef threadId As Integer) As String
Debug.Print("Wait Test begins.")
System.Threading.Thread.Sleep(term)
threadId = System.Threading.Thread.CurrentThread.ManagedThreadId
Return String.Format("Wait time was {0}.", term.ToString())
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim threadId As Integer
Dim awc As dlgtAsyncWaitChk
Dim result As IAsyncResult
Dim retValue As String
awc = New dlgtAsyncWaitChk(AddressOf waitTest)
result = awc.BeginInvoke(2000, threadId, Nothing, Nothing)
Debug.Print("Button1 thread {0} does some work.", System.Threading.Thread.CurrentThread.ManagedThreadId)
retValue = awc.EndInvoke(threadId, result)
Debug.Print("The call executed on thread {0}, with return value ""{1}"".", threadId, retValue)
End Sub
End Class
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*============================================================================*/