Проверка результатов от нескольких вызовов асинхронных веб-сервисов - PullRequest
0 голосов
/ 10 октября 2019

У меня есть несколько веб-сервисов, которые реализуют один и тот же интерфейс, который я хочу вызвать из другого приложения.

Для каждого веб-сервиса мне нужно вызвать два метода, A () и B () в этом порядке, и я хочу проверить ответ от каждого вызова на наличие ошибок (не исключений). И я пытаюсь сделать все это, используя async, но я пытаюсь понять, когда я могу проверить ответ от метода на наличие ошибок, если я проверяю после вызова async, то я получаю исключение 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");
 }

Однако respA будет нулевым, поскольку вызов A () является асинхронным. Возможно ли это, или мне нужно вызывать GetAwaiter (). GetResult () при вызове A () и B () отдельно?

Я все же хотел бы вызывать различные клиенты асинхронно, даже если мне приходится обрабатывать отдельные вызовы A () и B () на каждом клиенте синхронно - если это имеет смысл.

Спасибо, Канис.

1 Ответ

3 голосов
/ 10 октября 2019

Однако respA будет нулевым, поскольку вызов A () является асинхронным.

Не поэтому он null. Единственный способ respA может быть null, если 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, но заблокирует поток во время ожидания, что означает, что он больше не будет асинхронным.

Microsoft имеетдовольно хорошо написанные статьи по использованию async / await, которые я рекомендую вам прочитать. Они могут помочь вам точно понять, что происходит: Асинхронное программирование с асинхронностью и ожиданием

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...