是使用任务的Async/Await.异步运行以启动新线程



我读了很多文章,仍然无法理解这一部分。

考虑这个代码:

    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,该Task通过调用Task.Run(如果我没有错的话(从线程池创建线程,所有这些都异步运行。所以我实现了创建一个线程来完成我的工作,但异步完成?但考虑到我不需要返回任何结果,我只想在不返回任何结果的情况下完成工作,真的需要使用async/await吗?如果需要,如何使用?

第二个问题:

异步运行线程时,这是如何工作的?它是在主UI上运行,但在一个单独的线程上运行,还是在一个独立的线程上,并在该方法中异步运行?

  1. 创建异步方法的目的是为了以后可以等待它们。有点像"我要把水烧开,把剩下的汤料准备好,然后回到锅里,等水烧开了,这样我就可以做晚饭了。",但最终你必须停下来等待它。如果你想要的是"即发即弃",那么Async和Await就没有必要了

在C#中执行fire-and-forget方法的最简单方法?

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

1

如果你不await Taskawait它有很大的区别:

  • 如果您没有await,则:调用DoSomething,但执行下一句,而DoSomething Task尚未完成。

  • 如果await:调用DoSomething,一旦DoSomething Task完成,就执行下一句话。

因此,async/await的需求将取决于您想要如何调用DoSomething:如果您不调用await,则将其称为fire&忘记方式

2

它是在主UI上运行,但在单独的线程上运行,还是在运行在一个单独的线程上,而separate在其中异步方法

异步代码有时意味着其他线程(请参阅本问答异步与多线程-有区别吗?(。也就是说,如果代码是在独立于UI的线程中执行的,或者它允许在恢复UI线程时继续处理UI线程,这很好,因为UI循环仍然可以在并行执行其他任务时更新屏幕,而不会冻结UI。

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

有趣的问答;作为

你可能想复习一下其他的问答;As:

  • 异步/等待与线程
  • 什么';Task.Start/Wait和Async/Await有什么区别
  • async/await-什么时候返回Task vs void
  • Async await关键字是否等效于ContinueWith lambda

OP说

[…]但这是否意味着"async/await"将启动一个线程并Task。Run也会触发一个线程,还是它们都是同一个线程?

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

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);
}

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

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

最新更新