Avi*_*a00 13 .net c# multithreading visual-studio
我想知道在两个线程之间实现通信的最佳方法是什么.我有一个生成随机数的线程(类Sender),现在我想要另一个线程(类Receiver)接收生成的随机数.这是发件人:
public class Sender
{
public int GenerateNumber(){
//some code
return randomNumber;
}
}
Run Code Online (Sandbox Code Playgroud)
在Main函数中,我将启动这些线程:
static void Main(string[] args){
Sender _sender=new Sender();
Thread thread1=new Thread(new ThreadStart(_sender.GenerateNumber));
}
Run Code Online (Sandbox Code Playgroud)
我感谢您的帮助
Jon*_*eet 23
如果您使用的是.NET 4,我建议使用更高级别的抽象:Task<TResult>
.您的第一个线程可以安排任务(可能最终创建一个线程,或者在现有的任务处理线程上安排),然后可以检查状态,阻止结果等,因为它认为合适.
如果你想做的不仅仅是一次性任务,你可能想要使用生产者/消费者队列 - 再次,.NET 4帮助那个通过BlockingCollection<T>
.
这是使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
Task<TResult>
Jon Skeet在他的答案中指出的.NET 4中的类.信用证指示他指出.非常感谢,乔恩.我还没有理由使用该课程,当我看到它的使用方式时,我感到非常惊喜.
除了使用这个类在后面获得的性能优势之外,使用该类编写等效代码Task<TResult>
似乎更容易.例如,上面的Main方法的主体可以重写,如下所示:
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");
}
Run Code Online (Sandbox Code Playgroud)
如果您不需要为任务指定超时并且无限期地等待它完成,那么您可以使用更少的代码来编写它:
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);
Run Code Online (Sandbox Code Playgroud)