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

C#异步方法返回void和Task的区别
如果异步(async关键字)方法有返回值,返回类型为T时,返回类型必然是 Task。

但是如果没有返回值,异步方法的返回类型有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, 但返回值被c#教程忽略时,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 后就正常了:

1
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() 中的异常。如以下异常会被忽略。



```csharp
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#异步方法返回区别内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,你可以使用异步方法异步回调函数来实现异步操作。异步方法使用`async`关键字进行声明,并且返回类型应为`Task`或`Task<T>`。异步回调函数是一个委托,它会在异步操作完成时被调用。 下面是一个示例,展示了如何在C#中使用异步方法异步回调函数: ```csharp // 异步方法 public async Task MyAsyncMethod() { // 执行一些耗时的操作 await Task.Delay(1000); } // 异步回调函数 public void MyCallbackFunction(IAsyncResult result) { // 在这里处理异步操作完成后的逻辑 } // 使用异步方法异步回调函数 public async Task DoAsyncWork() { // 调用异步方法 await MyAsyncMethod(); // 创建一个异步回调委托 AsyncCallback callback = new AsyncCallback(MyCallbackFunction); // 开始异步操作,并指定回调函数 MyAsyncMethod().BeginInvoke(callback, null); // 继续执行其他操作 } ``` 在上面的示例中,`MyAsyncMethod`是一个异步方法,它使用`await`关键字等待一个耗时的操作。`DoAsyncWork`方法中,我们首先使用`await`关键字调用了`MyAsyncMethod`,以确保它完成后再继续执行下面的代码。 接下来,我们创建了一个异步回调委托`MyCallbackFunction`,它将在异步操作完成后被调用。然后,我们使用`BeginInvoke`方法启动异步操作,并传递回调函数。 请注意,这只是一个简单的示例,实际使用中可能会有更复杂的情况和需求。但是这应该能帮助你理解如何在C#中使用异步方法异步回调函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值