次の方法で共有


デリゲートの使用

非同期プログラミングでは、デリゲートを使用する呼び出し元は、メソッドを呼び出すときにデリゲートを定義する必要があります。最初にデリゲートを定義し、次にデリゲートのインスタンスを作成して、そのデリゲートを呼び出すコード例を次に示します。このサンプルでは、Factorize メソッドを非同期に呼び出すパターンを呼び出し元が定義します。

using System;
using System.Runtime.Remoting;

public delegate bool FactorizingAsyncDelegate(
         int factorizableNum, 
         ref int primefactor1,
         ref int primefactor2);

// This is a class that receives a callback when the results are available.
public class ProcessFactorizedNumber
{
   private int _ulNumber;

   public ProcessFactorizedNumber(int number)
   {
      _ulNumber = number;
   }

   // Note the qualifier one-way.
   [OneWayAttribute()]
   public void FactorizedResults(IAsyncResult ar)
   {
      int factor1=0, factor2=0; 

      // Extract the delegate from the AsyncResult.  
      FactorizingAsyncDelegate fd = 
         (FactorizingAsyncDelegate) ((AsyncResult)ar).AsyncDelegate;
      // Obtain the result.
      fd.EndInvoke(ref factor1, ref factor2, ar);

      // Output the results.
      Console.WriteLine("On CallBack: Factors of {0} : {1} {2}", 
                    _ulNumber, factor1, factor2);
   }
}
Asynchronous Variation 1 – call
// The Asynchronous Variation 1 call, calls
// the ProcessFactorizedNumber.FactorizedResults callback 
// when the call completes.
public void FactorizeNumber1()
{
   // The following is the Client code.
   PrimeFactorizer pf = new PrimeFactorizer();
   FactorizingAsyncDelegate fd = new FactorizingAsyncDelegate (pf.Factorize);

   // Asynchronous Variation 1
   int factorizableNum = 1000589023, temp=0; 

   // Create an instance of the class that is going 
   // to be called when the call completes.
   ProcessFactorizedNumber fc = new ProcessFactorizedNumber(factorizableNum);

   // Define the AsyncCallback delegate.
   AsyncCallback cb = new AsyncCallback(fc.FactorizedResults);

   // You can use any object as the state object.
   Object state = new Object();

   // Asynchronously invoke the Factorize method on pf.
   IAsyncResult ar = fd.BeginInvoke(
                        factorizableNum, 
                        ref temp, 
                        ref temp, 
                        cb, 
                        state); 

   //
   // Do some other useful work.
   //. . .
}
Asynchronous Variation 2
// Asynchronous Variation 2
// Waits for the result.
public void FactorizeNumber2()
{
   // The following is the Client code.
   PrimeFactorizer pf = new PrimeFactorizer();
   FactorizingAsyncDelegate fd = new FactorizingAsyncDelegate (pf.Factorize);

   // Asynchronous Variation 1
   int factorizableNum = 1000589023, temp=0; 

   // Create an instance of the class that is going 
   // to called when the call completes.
   ProcessFactorizedNumber fc = new ProcessFactorizedNumber(factorizableNum);

   // Define the AsyncCallback delegate.
   AsyncCallback cb = 
   new AsyncCallback(fc.FactorizedResults);

   // You can use any object as the state object.
   Object state = new Object();

   // Asynchronously invoke the Factorize method on pf.
   IAsyncResult ar = fd.BeginInvoke(
                     factorizableNum, 
                     ref temp, 
                     ref temp, 
                     null, 
                     null); 

   ar.AsyncWaitHandle.WaitOne(10000, false);

   if (ar.IsCompleted)
   {
      int factor1=0, factor2=0; 

      // Obtain the result.
      fd.EndInvoke(ref factor1, ref factor2, ar);

      // Output the results.

      Console.WriteLine("Sequential : Factors of {0} : {1} {2}", 
                    factorizableNum, factor1, factor2);

   }
}

メモ   非同期操作が完了する前に EndInvoke を呼び出すと、呼び出し元がブロックされます。同じ IAsyncResult を使用して EndInvoke を 2 回呼び出した場合の動作は未定義です。

参照   

非同期デリゲート | 非同期デリゲートのプログラミング サンプル