简体   繁体   中英

Checking results from multiple async web-service calls

I have a number of web-services which all implement the same interface which I want to call from another application.

On each web-service I need to call two methods, A() and B() in that order and I want to check the response from each call for errors (not exceptions). And I'm trying to do this all using async, but I'm struggling to understand when can I check the response from method for errors, if I check after the call to async then I get a NullReferenceException (understandably), but how do I combine the results from the two methods?

The following is an outline of the code without any result checks

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();
 }

What I'd like to do is check the result from A() and if it fails, then throw an exception and the same for 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");
 }

However respA will be null as the call to A() is async. Is this possible or do I need to call GetAwaiter().GetResult() on the call to A() and B() separately?

I would still like to call the different clients async, even if I have to treat the individual calls to A() and B() on each client synchronously - if that makes sense.

Thanks, Canice.

However respA will be null as the call to A() is async.

That is not why it's null . The only way respA can be null is if A() returned null . If null is a valid return value, but a value you cannot work with, then just check for that too:

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");
}

The await keyword already unwraps the result for you, so there is no need to use GetAwaiter().GetResult() . Doing this:

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

would give you the same value in respA , but would block the thread while waiting for it, which means it would not be asynchronous anymore.

Microsoft has quite well written articles on using async / await that I recommend you read. They might help you understand exactly what's going on: Asynchronous programming with async and await

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM