关于c#:Async / Await使用Task.Run异步启动一个新线程吗?

Is Async/Await using Task.Run starting a new thread asynchronously?

我读了很多文章,但还是不能理解这一部分。

考虑此代码:

1
2
3
4
5
6
7
8
9
10
    private async void button1_Click(object sender, EventArgs e)
    {
        await Dosomething();
    }

    private async Task<string> Dosomething()
    {
        await Task.Run((() =>"Do Work"));
        return"I am done";
    }

第一个问题:

当我单击按钮时,它将调用dosomething,并等待通过调用task.run(如果我没有弄错)从线程池创建线程的任务,所有这些都将异步运行。所以我实现了创建一个线程来完成我的工作,但是异步地完成它?但是考虑到我不需要返回任何结果,我只是希望在不返回任何结果的情况下完成工作,是否确实需要使用异步/等待,如果需要,如何进行?

第二个问题:

异步运行线程时,如何工作?它是在主UI上运行,但在一个单独的线程上运行,还是在一个单独的线程上运行,而separate则在该方法内部异步运行?


  • 创建异步方法的目的是让您以后可以等待它们。有点像"我要把这水烧开,把剩下的汤料准备好,然后回到锅里等水烧完,这样我就可以做晚饭了。"你开始把水烧开,当你做其他事情的时候,它是异步的,但最终你必须停下来等它。如果你想要的是"发射并忘记",那么异步和等待是不必要的。
  • 在C中使用最简单的方法来进行火和忘记方法。

  • 启动新任务会将该任务排队,以便在线程池线程上执行。线程在进程上下文中执行(例如,运行应用程序的可执行文件)。如果这是在IIS下运行的Web应用程序,则该线程是在IIS工作进程的上下文中创建的。该线程与主执行线程分开执行,因此无论主执行线程在做什么,它都会关闭并执行它的事情,同时,主执行线程会继续执行自己的工作。

  • 类型Task要求您从任务中返回TResult。如果您没有要返回的内容,可以使用Task代替(顺便说一下,它是Task的基类)。

    但请记住,任务不是线程。任务是要完成的任务,而线程是工作线程。随着程序的运行,工作和工作人员变得可用和不可用。在幕后,库将把您的作业分配给可用的工人,并且,由于创建新工人是一个昂贵的操作,所以它通常更喜欢通过线程池重用现有的工人。


    如果你不使用awaitTaskawait的话,有很大的区别:

    • 如果你不叫await它:DoSomething被调用,但下一句被执行,而DoSomethingTask还没有完成。

    • 如果你是await它:DoSomething被调用,下一句话在DoSomethingTask完成后执行。

    因此,asyncawait的需求将取决于你如何称呼DoSomething:如果你不称呼await,就像称呼它为火与忘记的方式。

    Is it running on the main UI but on a separate thread or is it running
    on a seperate thread and separate is asynchronously inside that
    method?

    异步代码有时意味着其他线程(参见本问题和异步与多线程——有区别吗?)。也就是说,如果代码是在与用户界面线程分离的线程中执行的,或者它允许用户界面线程在恢复时继续处理,这很好,因为用户界面循环仍然可以在其他任务并行执行时更新屏幕,而不会冻结用户界面。

    异步方法(即async方法)是一种句法上的制糖,用来告诉编译器await语句应被视为状态机。C编译器将您的async/await代码转换为状态机,在该状态机中等待Task结果的代码在等待的代码之后执行。

    有趣的问答

    您可能希望查看以下其他问题:

    • 异步/等待vs线程
    • task.start/wait和async/wait有什么区别?
    • 异步/等待-什么时候返回任务vs void?
    • async await关键字是否等效于具有lambda的continuewWith?

    奥普说…

    [...] But does this mean that"async/await" will fire off a thread and
    Task.Run also fires off a thread or are they both the same thread?

    使用async-await并不意味着"我创建了一个线程"。以优雅的方式实现延续只是一种句法上的甜头。任务可以是线程,也可以不是线程。例如,Task.FromResult(true)创建了一个假任务,以便能够实现异步方法而无需创建线程:

    1
    2
    3
    4
    5
    6
    public Task<bool> SomeAsync()
    {
        // This way, this method either decides if its code is asynchronous or
        // synchronous, but the caller can await it anyway!
        return Task.FromResult(true);
    }