Task.Run()和await Task.Run()有什么区别?

时间:2016-05-21 09:02:50

标签: c# multithreading asynchronous

以下程序是使用通用Task.Run()并使用async和await(异步)设计的。在这两种情况下,从线程池中获取不同的线程以用于新任务。那么区别是什么呢?异步意味着它应该使用主线程并释放它直到任务完成。但它也使用另一个线程而不是使用主线程。

public class Worker2
{
    public bool IsComplete { get; private set; }
    internal void DoWork()
    {
        this.IsComplete = false;
        Console.WriteLine("Doing Work.");
        Task.Run(new Action(LongOperation));
        Console.WriteLine("Work Completed");
        IsComplete = true;
    }

    private void LongOperation()
    {
            Console.WriteLine("long operation thread thread :" + Thread.CurrentThread.ManagedThreadId);//Thread Id = 7. it is different from main thread id.
            Console.WriteLine("Working!");
            Thread.Sleep(3000);
    }
}

//异步

public class Worker2
{
    public bool IsComplete { get; private set; }
    internal async void DoWork()
    {
        this.IsComplete = false;
        Console.WriteLine("Doing Work.");       
        await LongOperation();
        Console.WriteLine("Work Completed");
        IsComplete = true;
    }

    private Task LongOperation()
    {

        return Task.Run(() =>
            {
                Console.WriteLine("long operation thread thread :" + Thread.CurrentThread.ManagedThreadId);
                Console.WriteLine("Working!");
                Thread.Sleep(3000);
            });
    }
}

2 个答案:

答案 0 :(得分:11)

  

Task.Run()和await Task.Run()之间有什么区别?

第一个启动任务,然后在任务完成后立即完成工作,在任务完成之前

第二个启动任务,然后不同工作,直到任务完成,此时它在任务完成后完成工作。

让我们做个比喻。你的第一个程序就像这样做:

  • 雇人去割草坪。
  • 告诉你的配偶修剪草坪。
  • 去看Netflix。

你的第二个项目是:

  • 雇人去割草坪。
  • 在修剪草坪的同时观看Netflix。
  • 当割草完成并且电影结束时,告诉配偶割草坪。

显然,这些是非常不同的工作流程。两者都是异步的,但只有后者在其中有异步等待。我们异步等待告诉配偶割草坪直到它实际被修剪

答案 1 :(得分:4)

您误解了异步代码的含义。每当你调用任何函数时(委托)将实际代码执行传递给其他实体(其他专用线程,线程池等)并且函数会立即返回异步调用。异步调用是阻塞调用的对象。

在C#中有一些编写异步代码的方法,await / async只是简化了编写。它在语言功能方面没有增加任何内容。通过提供一种以我们编写阻塞代码的相同样式编写异步代码的方式,使程序更容易编写只是语法糖。

话虽这么说,Task.Run(new Action(LongOperation));是一个异步调用,也是来自第二个代码段的LongOperation()。它们之间的区别在于,在第一个示例中,当Task.Run返回紧跟在该行之后立即执行的代码时(如果没有发生线程切换)。在第二个示例中,await后面的行仅在线程池提供的某个线程上完成LongOperation时执行(DoWork在遇到await时立即返回)。

我建议您详细了解TPLasync / await。关于这两者的博客文章很多,更不用说详细介绍所有这些功能的好书了。