Utilizar delegados
En la programación asincrónica, si el que llama va a utilizar un delegado, debe definirlo al llamar a un método. En el siguiente código de ejemplo, se define primero el delegado, después se crea una instancia del mismo y, por último, se le llama. En el ejemplo siguiente se muestra cómo el que llama define un modelo para llamar asincrónicamente al método 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);
}
}
Nota Si se llama a EndInvoke antes de completar la operación asincrónica, el que llama quedará bloqueado. El resultado de llamar por segunda vez con la misma interfaz IAsyncResult es indefinido.
Vea también
Delegados asincrónicos | Ejemplo de programación de delegados asincrónicos