Вот возможный подход с использованием 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);
}
}
Я просто хотел обновить свой ответ, чтобы обеспечить то, что я думаю, что это эквивалентный код для приведенного выше примера, используя
Task<TResult>
класс в. NET 4, которую указал Джон Скит в своем ответе. Кредит идет к нему, чтобы указать на это. Большое спасибо, Джон. У меня еще не было причины использовать этот класс, и я был приятно удивлен, когда увидел, как легко его использовать.
Помимо преимуществ производительности, которые вы получаете под капотом от использования этого класса, писать эквивалентный код с использованием класса Task<TResult>
представляется намного проще. Например, тело главного метода выше, может быть переписан, как показано ниже:
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");
}
Если у вас нет необходимости указывать тайм-аут для выполнения этой задачи и содержание ждать неопределенно долго для того, чтобы закончить, то вы можете написать это использование еще меньше кода:
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);
Создаются ли оба потока одновременно? Что делает приемник, пока он ждет Отправителя? Что делает Отправитель после генерации случайного числа? – cadrell0
Является ли это .NET 4? – Yahia
На главной функции я начну оба потока, и отправитель потока будет работать, а затем спать в течение 3 секунд. Также я начну экземпляр приемника потока, который будет получать данные ...basiclly threads ll work untui user press esc key ... reciever ll записывает на полученные номера консоли. – Avicena00