He aquí un posible enfoque utilizando un WaitHandle:
class Program
{
static void Main(string[] args)
{
Sender _sender = new Sender();
Receiver _receiver = new Receiver();
using (ManualResetEvent waitHandle = new ManualResetEvent(false))
{
// have to initialize this variable, otherwise the compiler complains when it is used later
int randomNumber = 0;
Thread thread1 = new Thread(new ThreadStart(() =>
{
randomNumber = _sender.GenerateNumber();
try
{
// now that we have the random number, signal the wait handle
waitHandle.Set();
}
catch (ObjectDisposedException)
{
// this exception will be thrown if the timeout elapses on the call to waitHandle.WaitOne
}
}));
// begin receiving the random number
thread1.Start();
// wait for the random number
if (waitHandle.WaitOne(/*optionally pass in a timeout value*/))
{
_receiver.TakeRandomNumber(randomNumber);
}
else
{
// signal was never received
// Note, this code will only execute if a timeout value is specified
System.Console.WriteLine("Timeout");
}
}
}
}
public class Sender
{
public int GenerateNumber()
{
Thread.Sleep(2000);
// http://xkcd.com/221/
int randomNumber = 4; // chosen by fair dice role
return randomNumber;
}
}
public class Receiver
{
public void TakeRandomNumber(int randomNumber)
{
// do something
System.Console.WriteLine("Received random number: {0}", randomNumber);
}
}
Sólo quería actualizar mi respuesta para proporcionar lo que creo que es el código equivalente para el ejemplo anterior utilizando la clase
Task<TResult>
en. NET 4 señalado por Jon Skeet en su respuesta. El crédito va a él por señalarlo. Muchas gracias, Jon. Todavía no tengo una razón para usar esa clase, y me sorprendió gratamente cuando vi lo fácil que era usarla.
Aparte de los beneficios de rendimiento que obtiene bajo el capó de usar esta clase, escribir el código equivalente usando la clase Task<TResult>
parece ser mucho más fácil. Por ejemplo, el cuerpo del método principal de arriba puede ser reescrito como se muestra a continuación:
Sender _sender = new Sender();
Receiver _receiver = new Receiver();
Task<int> getRandomNumber = Task.Factory.StartNew<int>(_sender.GenerateNumber);
// begin receiving the random number
getRandomNumber.Start();
// ... perform other tasks
// wait for up to 5 seconds for the getRandomNumber task to complete
if (getRandomNumber.Wait(5000))
{
_receiver.TakeRandomNumber(getRandomNumber.Result);
}
else
{
// the getRandomNumber task did not complete within the specified timeout
System.Console.WriteLine("Timeout");
}
Si usted no tiene ninguna necesidad de especificar un tiempo de espera para la tarea y está dispuesto a esperar indefinidamente a que termine, entonces usted puede escribir esto usando aún menos código:
Sender _sender = new Sender();
Receiver _receiver = new Receiver();
Task<int> getRandomNumber = Task.Factory.StartNew<int>(_sender.GenerateNumber);
// begin receiving the random number
getRandomNumber.Start();
// ... perform other tasks
// accessing the Result property implicitly waits for the task to complete
_receiver.TakeRandomNumber(getRandomNumber.Result);
¿Comienzan ambos hilos al mismo tiempo? ¿Qué está haciendo Receiver mientras espera al remitente? ¿Qué hace el emisor después de generar un número aleatorio? – cadrell0
¿ES esto .NET 4? – Yahia
En la función principal, iniciaré ambos subprocesos y el remitente de subprocesos funcionará y luego dormirá durante 3 segundos. También voy a iniciar la instancia de receptor de hilo que recibirá datos ...basiclly threads 'll work untui user Presione la tecla esc ... reciever ll write en los números de consola que recibió. – Avicena00