ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

デリゲートの非同期呼び出し

プログラミングC# p320

デリゲートを非同期に呼び出して、結果を別のメソッドで処理します。ちょっとAjaxというかXmlHttpRequestっぽい。

using System;
using System.Threading;

class FunctionPointer
{
        public delegate int twoitem(int a, int b);

        public static int add(int a, int b)
        {
                return a + b;
        }

        public static int sub(int a, int b)
        {
                return a - b;
        }

        private static void DisplayResult(IAsyncResult ar)
        {
                // キャストして元のデリゲートを取得する
                FunctionPointer.twoitem ptr = (FunctionPointer.twoitem)ar.AsyncS
tate;

                int result = ptr.EndInvoke(ar);
                Console.WriteLine("result = {0}", result);
        }

        static void Main(string[] args)
        {
                // 関数ポインタを定義
                FunctionPointer.twoitem fp;

                fp = FunctionPointer.add;

                fp += FunctionPointer.sub;

                fp += delegate(int a, int b)
                {
                        return a * b;
                };

                foreach(FunctionPointer.twoitem ptr in fp.GetInvocationList())
                {
                        ptr.BeginInvoke(5, 3, new AsyncCallback(DisplayResult),
ptr);
                }

                Console.WriteLine("非同期呼び出し完了");

                Thread.Sleep(1000);
        }
}

結果はこう。

非同期呼び出し完了
result = 8
result = 2
result = 15

BeginInvokeで非同期デリゲート呼び出しを行い、その引数で渡したAsyncCallbackのメソッドでデリゲートの結果に対して処理を行う。
BeginInvokeはライブラリリファレンスには載ってませんが、デリゲートの引数 + AsyncCallback + デリゲートオブジェクト自身を引数に受け取るようです。
ちなみに最後にSleepを入れたのは、これを入れなかった場合何も表示されなかったからです。多分、非同期メソッド呼び出しが行われる前に、Main自体が終了してしまっているようなのですが、そんなのアリなんですかね?良く分かりません。。