fenri's diary

基本的には勉強し始めたC#のメモ。後は140字で収まらない駄文。

BeginInvoke

// デリゲート型の宣言
public delegate string AsyncMethodCaller(int targetCount, out int executeCount);

// デリゲート型の変数に関数を登録
AsyncMethodCaller caller = someExec;

// 非同期処理後の動作を設定
AsyncCallback callback = new AsyncCallback(AsyncCallbackMethod);

int executeCount = 0, targetCount = 5;

// 処理回数と処理済み回数を引数にして非同期実行
IAsyncResult result = caller.BeginInvoke(targetCount, out executeCount, callback, caller);


caller.BeginInvoke はデリゲート型変数に登録した someExecが呼ばれる

caller.BeginInvoke の引数で渡してるコールバック関数は someExecが終わったあとに呼ばれる
someExecの戻り値を IAsyncResult としてもらう。


EndInvoke はデリゲートの引数の中で、outとrefで定義した引数を引き継げる。


BeginInvoke メソッドは、非同期呼び出しを開始します。
 このメソッドは、非同期的に実行するメソッドと同じパラメーターと共に、2 つの省略可能な追加パラメーターを持っています。
 最初のパラメーターは、同期呼び出しが完了したときに呼び出されるメソッドを参照する AsyncCallback デリゲートです。
 2 番目のパラメーターは、コールバック メソッドに情報を渡すユーザー定義オブジェクトです。
 BeginInvoke からは制御がすぐに戻り、非同期呼び出しが完了するまで待機しません。
 BeginInvoke は IAsyncResult を返します。
 これを使用して非同期呼び出しの進捗状況を監視できます。

EndInvokeメソッドは、非同期呼び出しの結果を取得します。
 このメソッドは、BeginInvoke の後であればいつでも呼び出すことができます。
 非同期呼び出しがまだ完了していない場合は、EndInvoke は非同期呼び出しが完了するまで呼び出し元スレッドをブロックします。
 EndInvoke のパラメーターには、
  非同期実行するメソッドの out パラメーターと ref パラメーターと、BeginInvoke によって返された IAsyncResult が含まれます。




// delegateの宣言
public delegate string AsyncMethodCaller(int targetCount, out int executeCount);


private void button1_Click(object sender, EventArgs e)
{
	int executeCount = 0;
	int targetCount = 5;

	// デリゲート型の変数に関数を登録
	AsyncMethodCaller caller = new AsyncMethodCaller(someExec);

	//非同期処理後の動作を設定
	AsyncCallback callback = new AsyncCallback(AsyncCallbackMethod);

	//処理回数と処理済み回数を引数にして非同期実行
	IAsyncResult result = caller.BeginInvoke(targetCount, out executeCount, callback, caller);

	Console.WriteLine("処理回数:" + targetCount);

}


/// Invokeで呼ばれる関数
/// </summary>
/// <param name="targetCount"></param>
/// <param name="executeCount"></param>
/// <returns></returns>
static string someExec(int targetCount, out int executeCount)
{
	for (executeCount = 0; executeCount < targetCount; executeCount++)
	{
Console.Write("○");
Thread.Sleep(1000);
	}
	return "終わり";
}

/// <summary>
/// BeginInvokeのcallback関数 someExec終わりに呼ばれる
/// </summary>
/// <param name="ar"></param>
static void AsyncCallbackMethod(IAsyncResult ar)
{
	AsyncMethodCaller caller = (AsyncMethodCaller)ar.AsyncState;
	int executeCount = 0;
	// デリゲートの非同期実行結果を取得
	string resultString = caller.EndInvoke(out executeCount, ar);
	// 引数のout executeCountは デリゲート宣言時の引数の中で
	// ref または out キーワードを付けた引数と
	// IAsyncResult インターフェース型の引数を持つ。

	// 非同期処理結果を画面に表示
	Console.Write(Environment.NewLine + resultString + ":" + executeCount + "回");
}