首页 > 解决方案 > 检查多个异步 Web 服务调用的结果

问题描述

我有许多 Web 服务,它们都实现了我想从另一个应用程序调用的相同接口。

在每个 Web 服务上,我需要按顺序调用两个方法 A() 和 B(),并且我想检查每个调用的响应是否有错误(不是异常)。我正在尝试使用异步来完成这一切,但我很难理解何时可以检查方法的响应是否有错误,如果我在调用异步之后检查,那么我会得到一个 NullReferenceException(可以理解),但是怎么做我将两种方法的结果结合起来?

以下是没有任何结果检查的代码大纲

List<DeviceClient>  clients; // List of client interfaces to web-service
var startTasks = clients.Select(dc => SetupDevice(dc.Client);
await Task.WhenAll(startTasks);
...

 private async Task SetupDevice(DeviceClient client)
 {   
  await client.A();
  await client.B();
 }

我想做的是检查 A() 的结果,如果失败,则抛出异常,B() 也是如此。

 private async Task SetupDevice(DeviceClient client)
 {   
  var respA = await client.A();
  if (respA.Error)
    throw new Exception("A failed");

  var respB = await client.B();
  if (respB.Error)
    throw new Exception("B failed");
 }

但是,由于对 A() 的调用是异步的,因此 respA 将为 null。这是可能的还是我需要分别调用 A() 和 B() 时调用 GetAwaiter().GetResult() ?

我仍然想异步调用不同的客户端,即使我必须同步处理每个客户端上对 A() 和 B() 的单独调用——如果这有意义的话。

谢谢,卡尼斯。

标签: c#asp.net-coreasync-await

解决方案


但是,由于对 A() 的调用是异步的,因此 respA 将为 null。

这不是它的原因null。唯一的方法respAnull如果A()返回null。如果null是一个有效的返回值,但是一个你不能使用的值,那么也检查一下:

private async Task SetupDevice(DeviceClient client)
{   
  var respA = await client.A();
  if (respA == null || respA.Error)
    throw new Exception("A failed");

  var respB = await client.B();
  if (respB == null || respB.Error)
    throw new Exception("B failed");
}

关键字已经为您解开结果await,因此无需使用GetAwaiter().GetResult(). 这样做:

var respA = client.A().GetAwaiter().GetResult();

会给你相同的值respA,但会在等待线程时阻塞线程,这意味着它不再是异步的。

微软有相当不错的关于使用async/的文章await,我建议你阅读。它们可能会帮助您准确了解正在发生的事情:使用 async 和 await 进行异步编程


推荐阅读