C#异步方法返回void与Task的区别详解
作者:金庆 发布时间:2021-06-29 10:00:35
C#异步方法返回void和Task的区别
如果异步(async关键字)方法有返回值,返回类型为T时,返回类型必然是 Task<T>。
但是如果没有返回值,异步方法的返回类型有2种,一个是返回 Task, 一个是返回 void:
public async Task CountDownAsync(int count)
{
for (int i = count; i >= 0; i--)
{
await Task.Delay(1000);
}
}
public async void CountDown(int count)
{
for (int i = count; i >= 0; i--)
{
await Task.Delay(1000);
}
}
调用时,如果返回 Task, 但返回值被忽略时,VS 会用绿色波浪线警告:
CountDownAsync(3);
~~~~~~~~~~~~~~~~~
信息为:
(awaitable) Task AsyncExample.CountDownAsync(int count)
Usage:
await CountDownAsync(...);Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
中文为:
CS4014:由于此调用不会等待,因此在此调用完成之前将会继续执行当前方法。请考虑将"await"运算符应用于调用结果。
添加 await 后就正常了:
await CountDownAsync(3);
如果调用者不是一个异步方法,因为只有在异步方法中才可以使用 await,
或者并不想在此等待,如想同时执行多个 CountDownAsync(),
就不能应用 await 来消除警告。
此时可以改用 void 返回值的版本:
void Test()
{
...
CountDown(3);
CountDown(3);
...
}
async void CountDown(int count)
{
for (int i = count; i >= 0; i--)
{
await Task.Delay(1000);
}
}
Never call async Task methods without also awaiting on the returned Task. If you don't want to wait for the async behaviour to complete, you should call an async void method instead.
摘自:http://www.stevevermeulen.com/index.php/2017/09/using-async-await-in-unity3d-2017/
CountDown() 可以直接调用 CountDownAsync() 实现:
async void CountDown(int count)
{
await CountDownAsync(count);
}
使用下划线变量忽略异步方法的返回值也可以消除警告:
void Test()
{
...
_ = CountDownAsync(3);
_ = CountDownAsync(3);
...
}
但是这样同时也会忽略 CountDownAsync() 中的异常。如以下异常会被忽略。
void Test()
{
...
_ = CountDownAsync(3);
...
}
async Task CountDownAsync(int count)
{
for (int i = count; i >= 0; i--)
{
await Task.Delay(1000);
}
throw new Exception();
}
如果是调用返回 void 的异步方法,Unity 会报错:
Exception: Exception of type 'System.Exception' was thrown.
对 Async 后缀的说明
You could say that the Async suffix convention is to communicate to the API user that the method is awaitable. For a method to be awaitable, it must return Task for a void, or Task<T> for a value-returning method, which means only the latter can be suffixed with Async.
摘自:https://stackoverflow.com/questions/15951774
grpc 生成的代码中,异步请求返回了一个 AsyncCall 对象,AsyncCall 实现了 GetAwaiter() 接口:
public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, ...)
可以这样调用并等待:
var resp = await client.GetFeatureAsync(req);
虽然返回类型不是Task<>, 但是可等待,所以添加了 Async 后缀。
总结
来源:https://blog.csdn.net/jq0123/article/details/114064557


猜你喜欢
- 1.可见性通常,我们无法保证执行读操作的线程能看到其他线程写入的值,因为每个线程都由自己的缓存机制。为了确保多个线程之间对内存写入操作的可见
- 我就废话不多说了,大家还是直接看代码吧~public int read(byte[] b) throws IOException
- 动态规划的基本思想是将待求解问题分解成若干个子问题,先求解子问题,并将这些子问题的解保存起来,如果以后在求解较大子问题的时候需要用到这些子问
- 最近项目需要实现PDF下载的功能,由于没有这方面的经验,从网上花了很长时间查找了相关的资料。整理之后,发现有几个框架可以实现这个功能。1.
- 如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;如果要保证线程安全,自然是Str
- 调试的时候,在循环里增加条件判断,可以极大的提高效率,心情也能愉悦。以下介绍下IDEA使用条件【Condition】断点的方法1、编写一段样
- 最近在做一个项目,遇到了项目打成 war 包的一个问题,项目创建时选择的时 jar 包方式,后因项目部署要求,需要打成 war 包部署,遇到
- 1 简介AOP,即面向切面编程是很常用的技术,特别是在Java Web开发中。而最流行的AOP框架分别是Spring AOP和AspectJ
- Spring Boot 最主要的特性就是AutoConfig(自动配置),而对于我们这些使用者来说也就是各种starter,Spring B
- 一、配置逆向generatoe.xml<?xml version="1.0" encoding="UTF
- Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而
- 一、封装的查询方法/*** solr查询方法* @param client solr客户端* @param query solr查询对象*
- 本文实例为大家分享了Unity实现切割图集工具的具体代码,供大家参考,具体内容如下操作步骤先将脚本拖入Editor1.选中要切割的图片,te
- 高斯模糊高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像
- 一、项目运行环境配置:Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe
- ViewFlipper实现文字轮播(仿淘宝头条垂直滚动广告),供大家参考,具体内容如下广告条目可以单独写成布局文件,然后在布局文件或者代码中
- 效果明细用Popup实现的,录gif时,Popup显示不出来,不知道为什么,所以静态图凑合看吧大体思路图表使用Arc+Popup实现图表分为
- 流程图 * vs过滤器 * 是SpringMVC的技术过滤器的Servlet的技术先过过滤器,过滤器过完才到DispatcherServle
- 本文实例为大家分享了C#实现快速排序的具体代码,供大家参考,具体内容如下代码:/// <summary> /// 排序 ///
- 效果:原图加水印后的图片废话不多说,直接上代码代码:package com.example.demo;import java.awt.Alp