C#异步方法返回void与Task的区别详解

 更新时间:2021年03月04日 12:03:56   作者:金庆  
这篇文章主要给大家介绍了关于C#异步方法返回void与Task的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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 后缀。

总结

到此这篇关于C#异步方法返回void与Task区别的文章就介绍到这了,更多相关C#异步方法返回区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#有效防止同一账号多次登录(附三种方法)

    C#有效防止同一账号多次登录(附三种方法)

    这篇文章主要介绍了C#有效防止同一账号多次登录的方法,有效防止同一账号多次登录的方法很多,比如用数据库来记录用户登录情况、用Application来保存用户登录信息、用Cache来保存信息等,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • C#使用iTextSharp设置PDF所有页面背景图功能实例

    C#使用iTextSharp设置PDF所有页面背景图功能实例

    这篇文章主要介绍了C#使用iTextSharp设置PDF所有页面背景图功能,实例分析了C#使用iTextSharp设置PDF页面背景图的实现方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • C#基础知识系列八const和readonly关键字详细介绍

    C#基础知识系列八const和readonly关键字详细介绍

    这篇文章主要介绍了C#中的const和readonly关键字,有需要的朋友可以参考一下
    2014-01-01
  • C#生成本地配置文件的实现示例

    C#生成本地配置文件的实现示例

    本文将介绍如何使用C#语言生成本地配置文件,以便为应用程序提供灵活的配置选项,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01
  • C#实现高效查找替换Excel表格数据或文本

    C#实现高效查找替换Excel表格数据或文本

    在现代数据驱动的业务环境中,Excel表格扮演着不可或缺的角色,本文将深入探讨如何利用C#编程语言,精准地实现Excel表格中的数据和文本查找与替换,感兴趣的小伙伴可以了解下
    2025-09-09
  • C#生成Word文档代码示例

    C#生成Word文档代码示例

    这篇文章主要介绍了C#生成Word文档代码示例,本文直接给出代码实例,需要的朋友可以参考下
    2015-06-06
  • 详解C# parallel中并行计算的四种写法总结

    详解C# parallel中并行计算的四种写法总结

    在C#中,parallel关键字可以用于并行计算。本文为大家总结了四种C# parallel并行计算的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-11-11
  • Unity游戏之存储数据

    Unity游戏之存储数据

    这篇文章主要介绍了Unity游戏之存储数据,感兴趣的同学,可以拷贝代码,试验一下
    2021-04-04
  • C#图片加载慢的具体原因和解决方法

    C#图片加载慢的具体原因和解决方法

    这篇文章主要讨论了在C#中优化图片加载的三个关键点:使用异步加载、正确使用图片类和对图片进行适当的压缩和缓存,通过避免这些致命错误,可以显著提高应用程序的性能和用户体验,需要的朋友可以参考下
    2025-11-11
  • 详解c#索引(Index)和范围(Range)

    详解c#索引(Index)和范围(Range)

    这篇文章主要介绍了c#索引(Index)和范围(Range)的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-10-10

最新评论