¿Cómo hacer una serie de llamadas asincrónicas y luego usar el valor devuelto por el primer hilo?
Frecuentes
Visto 144 veces
2
Quiero hacer llamadas asincrónicas y luego procesar el valor devuelto por el primer hilo. No quiero usar la biblioteca paralela. Solo puedo usar .Net 2.0. He escrito el siguiente programa que debería ser suficiente para mis requisitos. Pero, ¿alguien puede señalar si hay una solución mejor? Gracias.
Aquí está mi código:
class Program
{
private static Worker _worker2;
private static Worker _worker3;
private static Worker _worker4;
private static Worker _worker1;
delegate void DoWorkDelegate(object param);
private static Worker _firstReturnedWorker = null;
private static object lockObject = new object();
public static void Main()
{
_worker1 = new Worker();
_worker2 = new Worker();
_worker3 = new Worker();
_worker4 = new Worker();
int i = 10;
DoWorkDelegate d1 = new DoWorkDelegate(_worker1.OnDoWork);
d1.BeginInvoke(1, OnThreadReturned, ++i);
DoWorkDelegate d2 = new DoWorkDelegate(_worker2.OnDoWork);
d2.BeginInvoke(2, OnThreadReturned, ++i);
DoWorkDelegate d3 = new DoWorkDelegate(_worker3.OnDoWork);
d3.BeginInvoke(3, OnThreadReturned, ++i);
DoWorkDelegate d4 = new DoWorkDelegate(_worker4.OnDoWork);
d4.BeginInvoke(4, OnThreadReturned, ++i);
Console.ReadKey();
}
private static void OnThreadReturned(IAsyncResult ar)
{
lock (lockObject)
{
if (_firstReturnedWorker == null)
{
var workerIdentifier = (int)ar.AsyncState;
switch (workerIdentifier)
{
case 11:
_firstReturnedWorker = _worker1;
break;
case 12:
_firstReturnedWorker = _worker2;
break;
case 13:
_firstReturnedWorker = _worker3;
break;
case 14:
_firstReturnedWorker = _worker4;
break;
}
}
else
{
return;
}
}
Console.WriteLine("First result received was {0}", _firstReturnedWorker.ReturnedValue);
}
}
public class Worker
{
public string ReturnedValue { get; private set; }
public void OnDoWork(object value)
{
ReturnedValue = Process((int)value);
}
private string Process(int numberToProcess)
{
return string.Format("{0} was processed by {1}", numberToProcess, Thread.CurrentThread.ManagedThreadId);
}
}
1 Respuestas
1
Su código parece que debería funcionar, así que está bien hasta ahora.
Podría limpiarlo un poco pasando los objetos de instancia de Worker como el AsyncState
en lugar del número mágico. Entonces no necesitarías el switch
in OnThreadReturned
ya sea.
La alternativa sería poner todos los IAsyncResult.AsyncWaitHandle
está en una matriz y llama WaitHandle.WaitAny
. Sin embargo, esto es más general, ya que el WaitHandle
se crean bajo demanda, por lo que no serán necesarios en su solución de devolución de llamada. Son objetos reales del núcleo, por lo que esto puede ser importante.
contestado el 03 de mayo de 12 a las 14:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c# .net multithreading .net-2.0 or haz tu propia pregunta.
Usar WaitHandler.WaitAny me parece más elegante. Pero, una vez que consiga el mango. ¿Cómo identifico qué instancia de trabajador se debe usar? var arrOfHandles = new WaitHandle[] { ai1.AsyncWaitHandle, ai2.AsyncWaitHandle, ai3.AsyncWaitHandle, ai4.AsyncWaitHandle }; var index = WaitHandle.WaitAny(arrOfHandles); var identificador = arrOfHandles[índice]; - Salvadera
El índice devuelto de
WaitHandle.WaitAny
es el índice en la matriz deWaitHandles
que pasas como parámetro. Así que si vuelve0
, tú lo sabes_worker1
completado primero. - nick mayordomo