等待来自多个线程的任务
Waiting on a Task from multiple threads
是否可以同时从两个不同的线程对同一个 Task
调用 Wait()
?
例如,下面的代码是否有效:
private BlockingCollection<Task> _queue = new BlockingCollection<Task>();
private Thread _taskPumpThread;
...
private void Run()
{
_taskPumpThread= new Thread(() => TaskPump(...));
_taskPumpThread.Start();
DoNothing();
}
private void DoNothing()
{
Task doNothing = new Task(() => Console.WriteLine("Doing nothing"));
queue.Add(doNothing);
doNothing.Wait(); // no try-catch for brevity
}
private void TaskPump(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
Task task = queue.Take();
task.Start();
task.Wait();
}
}
动机:
我正在实现一个控制器,它最终将请求序列化到串行端口,并处理来自端口的通知。请求可以从不同的线程发送,它们应该能够等待结果(或异常),但可以选择异步工作。
我正在考虑上面的设计,因为 Task
可以很好地处理所有情况(同步结果、异步调用和异常)。
可以找到一个相关但不完全相同的问题 here。
我只会回答您非常具体的问题。
如果你运行下面的短程序你会看到答案是是,你可以让多个线程等待同一个任务:
public static void Main(string[] args)
{
Task t = Task.Delay(10000);
new Thread(() => { ThreadRun(t); }).Start();
new Thread(() => { ThreadRun(t); }).Start();
Console.WriteLine("Main thread exits"); // this prints immediately.
}
private static void ThreadRun(Task t)
{
t.Wait();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " finished waiting"); // this prints about 10 seconds later.
}
是否可以同时从两个不同的线程对同一个 Task
调用 Wait()
?
例如,下面的代码是否有效:
private BlockingCollection<Task> _queue = new BlockingCollection<Task>();
private Thread _taskPumpThread;
...
private void Run()
{
_taskPumpThread= new Thread(() => TaskPump(...));
_taskPumpThread.Start();
DoNothing();
}
private void DoNothing()
{
Task doNothing = new Task(() => Console.WriteLine("Doing nothing"));
queue.Add(doNothing);
doNothing.Wait(); // no try-catch for brevity
}
private void TaskPump(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
Task task = queue.Take();
task.Start();
task.Wait();
}
}
动机:
我正在实现一个控制器,它最终将请求序列化到串行端口,并处理来自端口的通知。请求可以从不同的线程发送,它们应该能够等待结果(或异常),但可以选择异步工作。
我正在考虑上面的设计,因为 Task
可以很好地处理所有情况(同步结果、异步调用和异常)。
可以找到一个相关但不完全相同的问题 here。
我只会回答您非常具体的问题。
如果你运行下面的短程序你会看到答案是是,你可以让多个线程等待同一个任务:
public static void Main(string[] args)
{
Task t = Task.Delay(10000);
new Thread(() => { ThreadRun(t); }).Start();
new Thread(() => { ThreadRun(t); }).Start();
Console.WriteLine("Main thread exits"); // this prints immediately.
}
private static void ThreadRun(Task t)
{
t.Wait();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " finished waiting"); // this prints about 10 seconds later.
}