Await/Async 和 Task 的说明

     2023-03-30     286

关键词:

【中文标题】Await/Async 和 Task 的说明【英文标题】:Clarification for Await/Async and Task 【发布时间】:2015-06-02 15:10:02 【问题描述】:

最近我开始使用多线程,并试图更好地理解 await/async 和 Task。我输入了以下场景:

private void button1_Click(object sender, EventArgs e)

    var list = GenerateList();
    progressBar1.Maximum = list.Count ();

    CreateStuff (list));
    MessageBox.Show ("Complete!");


async void CreateStuff (List<int> list)

    //additional Parameters here used for DoWork()
    await Task.Run (()=>Parallel.ForEach(list, item =>
    
        DoWork();
        Invoke(new Action(() => progressBar1.PerformStep()));
    ));
    //do something that relies on list

我正在尝试在 CreateDocs 方法完成后显示消息框。一位同行告诉我,可以在 CreateStuff() 方法中继续使用 await async,并在显示消息框之前仍然等待该方法完成。我一直在研究 await async 和 Task 一段时间,但似乎无法弄清楚如何做到这一点。

对我来说,让 button1_Click() 使用 await 异步,然后 await CreateStuff() 方法似乎更容易。

我的问题是:是否可以在 CreateStuff 方法中继续使用 await async 并在显示消息框之前仍然等待 button1_Click() 中的 CreateStuff() 方法完成?

我假设它与返回任务有关,但我不太清楚如何进行。

感谢任何帮助。谢谢!

【问题讨论】:

【参考方案1】:

我的问题是:是否可以在 CreateStuff 方法中继续使用 await async 并在显示消息框之前仍然等待 button1_Click() 中的 CreateStuff() 方法完成?

当然——但您需要先更改CreateStuff 的返回类型。目前您正在返回void,这几乎不是一个好主意——它实际上只适用于事件处理程序。您只需将其更改为返回Task,即可等待:

async Task CreateStuff (List<int> list)

然后在您的点击处理程序(也需要异步)中,等待调用它的结果:

await CreateStuff (list);

请注意,CreateStuff 的实现是否真的很理想并不清楚。您不需要为此使用异步方法 - 您可以:

Task CreateStuff(List<int> list)

    return Task.Run(() => Parallel.ForEach(list, item =>
    
        DoWork();
        Invoke(new Action(() => progressBar1.PerformStep()));
    ));

当您可以只返回任务并让调用代码等待它时,存在仅用于创建任务并等待它的异步方法并没有多大意义。 (我怀疑它们的行为在某些方面略有不同,但在这种特殊情况下并不重要。)

【讨论】:

通过使用 await CreateStuff(list);在我的点击处理程序中,我还需要将异步添加到点击处理程序吗?而在我修改程序之前,我正在等待 CreateStuff 中的 Task 完成打印一行。 @user3311482:是的,您也需要点击处理程序是异步的,但这很简单。 出于好奇,将点击处理程序设为异步是否被认为是不好的做法? @Speerian: 不 - 事件处理程序基本上是异步方法允许返回void的唯一原因......而且它工作得非常好,因为你可以等待长时间运行的操作,然后访问 UI,因为继续在 UI 线程中触发。【参考方案2】:

你的问题是async void

你需要把CreateStuff()改成async Task,这样你就可以在调用点await了。

您应该只将async void 用于事件处理程序。

【讨论】:

unity中的异步编程——在unity中使用c#原生的异步(task,await,async)-system.threading.tasks(代码片段)

...。2、UniTask(Cysharp.Threading.Tasks)是仿照.Net原生的Task,await,async开发的一个包,该包专门服务于Unity,所以取名UnityTask,简称UniTask。3、既然有Task了,为啥还要搞一个UniTask(1)Task可以用在PC和Android上... 查看详情

async/await的串行和并行

参考技术A2.Promise then来实现3.通过async和await来实现1.只有在async修饰的方法中才可以使用await2.async修饰的方法会自动返回一个Promise1.await关键字还有可以在async修饰的方法中使用2.await后面必须要跟一个Promise3.await会将异步函数... 查看详情

异步编程之async和await(代码片段)

继续Dart异步编程的第五篇async和await。async和await是Dart异步编程用于简化异步API操作的两个关键字。它的作用就是能够将异步的代码使用同步的代码结构实现。相信学习过之前的Future和Stream的文章就知道,对于最终返回的值或者... 查看详情

promise与async和await的区别(代码片段)

什么是Async/Await?  async/await是写异步代码的新方式,以前的方法有回调函数和Promise。  async/await是基于Promise实现的,它不能用于普通的回调函数。  async/await与Promise一样,是非阻塞的。  async/await使得异步代码看起来像... 查看详情

foreach和await/async的问题(代码片段)

...件服务器的时候遇到了一个问题,在forEach循环里面调用await/async异步函数的问题。这个问题也遇到几次了,这里记下避免下次再忘。问题重现vargetNumbers=()=>returnPromise.resolve([1,2,3])varmulti=num=>returnnewPromise((resolve,reject)=>se 查看详情

如何在同一站点上的 ashx 和 aspx 文件中使用 await/async?

】如何在同一站点上的ashx和aspx文件中使用await/async?【英文标题】:HowcanIuseawait/asyncinbothaashxandaspxfilesonthesamesite?【发布时间】:2016-08-0308:35:15【问题描述】:我正在尝试在我的aspx页面的代码隐藏中运行异步任务。我正在使用Pag... 查看详情

理解es7中的async/await

理解ES7中的async/await  优势是:就是解决多层异步回调的嵌套 从字面上理解async/await,async是"异步"的含义,await可以认为是asyncwait的简写,因此可以理解async用于声明一个function是异步的,而await用于等待一个异步方法执... 查看详情

正确使用带有 Await/Async 的 Promise

】正确使用带有Await/Async的Promise【英文标题】:UsingPromiseswithAwait/AsyncCorrectly【发布时间】:2018-05-1805:44:53【问题描述】:我在理解Promise功能的工作原理时遇到了一些问题,我以前使用过Bluebird,但我想尝试学习新的await/async标准... 查看详情

async函数

async点:当函数执行时,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体后面的语句。async函数与generator函数相比,不同点:1.内置执行器。async函数自带执行器;与普通函数一模一样,只需一行即可调用。而genenra... 查看详情

[转]scalaasync库(scalafuture,await,async)(代码片段)

...ure代表一个异步计算,你可以设置你的回调函数或者利用Await.result等待获取异步计算的结果,你还可以组合多个future为一个新的future。Promise让你可以控制是否完成计算还是抛出异常,它的future方法返回一个Future对象,complete、succe... 查看详情

koa2的使用方法:(代码片段)

...3.npminstall//安装项目依赖;4.npmstart//启动项目  2.async和await:async(异步) asyncfunctiontest()return‘Helloasync‘constresult=test()console.log(result)  await(等待)?/***await等待async方法执完毕;*注释:await必须在async方法中可以使用因为await访... 查看详情

使用 await async 获取数据而不使用 try catch

】使用awaitasync获取数据而不使用trycatch【英文标题】:Getdatausingawaitasyncwithouttrycatch【发布时间】:2018-10-1700:41:22【问题描述】:我正在尝试使用没有try-catch的await-async:constgetUsers=async(reject,time)=>(newPromise((resolve,reject)=>setTimeo... 查看详情

在 webapi 中正确使用 await async

】在webapi中正确使用awaitasync【英文标题】:Correctusageofawaitasyncinwebapi【发布时间】:2013-08-1414:47:35【问题描述】:我有一个WebApi,它为每个传入请求调用2个单独的Web服务,执行一些后期处理并返回结果。第一个webservice调用在本... 查看详情

react利用await/async实现批量上传图片可预览可限制上传图片数量(代码片段)

es7提出的async/await概念已经存在有相当长一段时间,具体概念用法就不在这里赘述了,优势在于处理解决then链多层嵌套回调的问题,使得代码更为简单清晰。本文在这里要讲的是批量上传多张图片时,如果不分批上传可能触发浏... 查看详情

生产环境项目问题记录系列:同步方法调用异步方法

...种方式:()(1).....Async().Wait():失败,接口阻塞(2)await.....Async().ConfigureAwait(false)(3).....Async().Resutt()在上面这几种方法失败后,又去百度了几种方法,都不行,最后找到一种解决方式如下: Tasktask=Task.Run(async()=>a... 查看详情

es6的箭头函数转换为普通函数,以及将await/async函数转为普通函数

箭头函数转为普通函数:  1.安装babel-preset-es2015      npminstallbabel-preset-es2015--save-dev   2.在.babelrc文件夹中:      "presets":["es2015"] await/async函数转为普通函数:  1 查看详情

使用 .NET Core(.NET Standard 1.4 和 .NET Framework 4.6.1)对 System.Net.Http 使用 await/async 时出现错误?

....NETCore(.NETStandard1.4和.NETFramework4.6.1)对System.Net.Http使用await/async时出现错误?【英文标题】:Bugwhenusingawait/asyncforSystem.Net.Httpwith.NETCore(.NETStandard1.4and.NETFramework4.6.1)?【发布时间】:2017-01-1715:23:08【问题描述】:前景:我正在调 查看详情

关于function和task的说明

 1. 关于函数function调用,总结两个要点:      1. 函数调用一般产生一个值,这个值被赋值给某个变量      2. 函数所返回的值只能是一个,不可以是多个,不能像C语言中... 查看详情