C(※)委託の三種類の呼出例(同期呼出非同期呼出しの非同期コールバック)


まず、コードによって1つの依頼と以下の3つの例を定義すると呼び出される方法:

public delegate int AddHandler(int a,int b);
    public class
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine(" :" + a + "+" + b);
            Thread.Sleep(3000); //
            Console.WriteLine(" !");
            return a + b;
        }
    }
同期コール
依頼されたInvokeメソッドは同期呼び出しに使用されます。同期呼び出しは、現在のスレッドをブロックし、呼び出しを実行し、呼び出しが完了したら、下に進みます。

public class
{
        static void Main()
        {
            Console.WriteLine("===== SyncInvokeTest =====");
            AddHandler handler = new AddHandler( .Add);
            int result = handler.Invoke(1, 2);
            Console.WriteLine(" 。。。");
            Console.WriteLine(result);
            Console.ReadKey();
        }     
}
同期呼び出しはスレッドをブロックします。重い作業(例えば、大量のIO操作)を起動する場合、プログラムを長い間停止させ、悪いユーザー体験を引き起こす可能性があります。この場合、非同期呼び出しが必要です。
非同期呼び出し
非同期呼び出しは、スレッドをブロックするのではなく、スレッドプールに呼び込み、プログラムマスタスレッドまたはUIスレッドを継続して実行することができる。委託の非同期呼び出しはBeginInvokeとEnd Invokeによって実現される。

public class
{
        static void Main()
        {
            Console.WriteLine("===== AsyncInvokeTest =====");
            AddHandler handler = new AddHandler( .Add);
            //IAsyncResult: (interface)
            //BeginInvoke: (delegate)
            IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
            Console.WriteLine(" 。。。");
            //
            Console.WriteLine(handler.EndInvoke(result));
            Console.ReadKey();
        }
}
メインスレッドは待機していないが、そのまま下に向かって動作していることが分かります。しかし、問題は依然として存在しており、メインスレッドがEndInvokeに実行されている場合、起動が終了していない場合(この場合は発生する可能性があります)、呼出結果を待つためにスレッドがブロックされます。
非同期依頼は、以下のような書き方も参考にできます。
アクションaction=>method(obj);
action.BeginInvoke(obj,ar=>action.End Invoke(ar),null);
簡単な言葉で操作ができます。
非同期コールバック
コールが終了するとコールバック関数が自動的に呼び出され、呼び出し結果を待つためにスレッドがブロックされている状態を解決しました。

public class
{
        static void Main()
        {
            Console.WriteLine("===== AsyncInvokeTest =====");
            AddHandler handler = new AddHandler( .Add);
            // ( BeginInvoke !)
            IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback( ),"AsycState:OK");
            Console.WriteLine(" 。。。");
            Console.ReadKey();
        }

        static void (IAsyncResult result)
        {    
             //result “ .Add() ”
            //AsyncResult IAsyncResult , :System.Runtime.Remoting.Messaging
            //AsyncDelegate 。
            AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
            Console.WriteLine(handler.EndInvoke(result));
            Console.WriteLine(result.AsyncState);
        }
}

私が定義した依頼の種類はAddHandlerで、AddHandler.EndInvokeにアクセスするためには、非同期依頼をAddHandlerに強制変換しなければなりません。非同期コールバック関数でMAddHandler.EndInvokeを呼び出して、最初に提出されたAddHandler.BeginnInvokeの結果を得ることができる。
問題:
(1)int result=handle.Invoke(1,2)
なぜInvokeのパラメータと戻り値はAddhandler依頼と同じですか?
Invoke方法のパラメータは簡単で、一つはパラメータテーブル(オプション)であり、Invoke方法の主な機能はUIスレッド上で指定された方法を起動することを助けることである。Invoke方法は、まず、起動スレッド(現在のスレッド)がUIスレッドであるかどうかを確認し、もしそうでない場合は、UIスレッドに切り替えて、依頼先の方法を実行する。現在のスレッドがUIスレッドであるかどうかにかかわらず、Invokeは、委託先の方法が実行されるまでブロックされ、呼出スレッド(必要であれば)を切り替えて戻ってきます。
Invokeメソッドのパラメータと戻り値と彼の呼び出し依頼は一致するはずです。
(2)IAsyncResoult relt=handle.BeginnInvoke(1,2,null,null);
BeginninInvoke:非同期の要求を開始し、スレッドプールのスレッドを呼び出して実行します。
IAsyncResultオブジェクト(非同期のコア)に戻ります。IAsyncResultは、非同期動作の状態情報を格納するインターフェースと、現在の非同期を彼で終了することができます。
注意:BeginInvokeとEndInvokeはペアで起動しなければなりません。戻り値が必要でなくても、EndInvokeは必ず起動しなければなりません。メモリ漏れの原因になります。
(3)IAsync Result.Async State属性:
ユーザ定義のオブジェクトを取得し、非同期動作に関する情報を限定または含む。たとえば:

static void AddComplete(IAsyncResult result)

      AddHandler handler = (AddHandler)result.AsyncState;  
      Console.WriteLine(handler.EndInvoke(result));
}
完全コードは以下の通りです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;
namespace ConsoleTest
{
    public delegate int AddHandler(int a,int b);
    public class
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine(" :" + a + "+" + b);
            Thread.Sleep(3000); //
            Console.WriteLine(" !");
            return a + b;
       }
    }

    public class
    {
       static void Main()
        {
            Console.WriteLine("===== SyncInvokeTest =====");
            AddHandler handler = new AddHandler( .Add);
            int result = handler.Invoke(1, 2);

            Console.WriteLine(" 。。。");
            Console.WriteLine(result);
            Console.ReadKey();
        }
    }

    public class
    {
        static void Main()
        {
            Console.WriteLine("===== AsyncInvokeTest =====");
            AddHandler handler = new AddHandler( .Add);
            //IAsyncResult: (interface)
            //BeginInvoke: (delegate)
            IAsyncResult result = handler.BeginInvoke(1, 2, null, null);
            Console.WriteLine(" 。。。");
            //
            Console.WriteLine(handler.EndInvoke(result));
            Console.ReadKey();
        }
    }

    public class
    {
        static void Main()
        {
            Console.WriteLine("===== AsyncInvokeTest =====");
            AddHandler handler = new AddHandler( .Add);
            // ( BeginInvoke !)
            IAsyncResult result = handler.BeginInvoke(1,2,new AsyncCallback( ),"AsycState:OK");
            Console.WriteLine(" 。。。");
            Console.ReadKey();
        }

        static void (IAsyncResult result)
        {    
             //result “ .Add() ”
            //AsyncResult IAsyncResult , :System.Runtime.Remoting.Messaging
            //AsyncDelegate 。
            AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
            Console.WriteLine(handler.EndInvoke(result));
            Console.WriteLine(result.AsyncState);
        }
    }
}