如何在两个不同的线程上等待一个任务?

时间:2016-12-12 11:59:09

标签: c# .net multithreading async-await c#-7.0

我可以等待在不同线程上创建的任务吗?例如:

...
CurrentIteration = Execute(); // returns Task
await CurrentIteration;
...

然后,在另一个主题上:

...
await CurrentIteration;
...
  1. 第二个线程会等待Execute方法完成执行吗?
  2. 如果可以的话,我可以在第二个帖子中为同一目的重新使用CurrentIteration,因为我重新运行
  3. CurrentIteration = Execute(); // returns Task await CurrentIteration;

    在第一个帖子上?

    我试过这段代码:

    public class Program
    {
        public static void Main(string[] args)
        {
            MainAsync(args).GetAwaiter().GetResult();
        }
        public static async Task MainAsync(string[] args)
        {
    
            var instance = new SomeClass();
            var task = instance.Execute();
            Console.WriteLine("thread 1 waiting...");
            Task.Run(async () =>
            {
                Console.WriteLine("thread 2 started... waiting...");
                await task;
                Console.WriteLine("thread 2 ended!!!!!");
            });
    
            await task;
    
            Console.WriteLine("thread 1 done!!");
    
            Console.ReadKey();
        }
    }
    
    
    public class SomeClass
    {
        public async Task Execute()
        {
            await Task.Delay(4000);
        }
    }
    

    但它打印

    thread 1 waiting...
    thread 2 started... waiting...
    

    然后

    thread 1 done!!
    

    但永远不会thread 2 ended!!!!!。这是为什么?我怎样才能做到这一点?谢谢!

1 个答案:

答案 0 :(得分:6)

您可以await来自多个线程的任务。你实际上非常接近于让它工作,正如@Rob所说,你只需要await第二个线程。

考虑一下:

    public static async Task MainAsync(string[] args)
    {

        var instance = new SomeClass();
        var task = instance.Execute();
        Console.WriteLine("thread 1 waiting...");
        var secondTask = Task.Run(async () =>
        {
            Console.WriteLine("thread 2 started... waiting...");
            await task;
            Console.WriteLine("thread 2 ended!!!!!");
        });

        await task;

        await secondTask;

        Console.WriteLine("thread 1 done!!");

        Console.ReadKey();
    }

等完任务后,在第二个线程上添加等待。

您没有看到该指示的原因是因为控制台卡在ReadKey方法上,并且在完成之前无法写入任何内容。如果你按Enter键,你可以看到"线程2结束!!!!!"应用程序关闭前的第二行。