Utilisation des délégués
Avec la programmation asynchrone, l'appelant, s'il utilise un délégué, doit le définir en appelant une méthode. Dans l'exemple de code suivant, le délégué est d'abord défini puis une instance du délégué est créée puis appelée. L'exemple ci-dessous illustre l'appelant définissant un modèle pour l'appel de la méthode Factorize de manière asynchrone :
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);
}
}
Remarque L'appel à EndInvoke avant l'achèvement de l'opération asynchrone bloquera également l'appelant. Rien n'est défini en ce qui concerne le second appel à cette méthode avec le même IAsyncResult.
Voir aussi
Délégués asynchrones | Exemple de programmation de délégués asynchrones