简体   繁体   中英

Assigning result of async method to a variable

I'm looking at the "good" example in this scenario , specifically assigning the result of an async method to a variable. (In this case it's a discard variable but it works the same if I just do var x = ).

public void Heartbeat(object state)
{
    // Discard the result
    _ = DoAsyncPing();
}

private async Task DoAsyncPing()
{
    await _client.GetAsync("http://mybackend/api/ping");
}

In trying this myself, I notice that if I remove the _ variable, I get compiler warnings saying "this call is not awaited". Why does assigning the result make a difference to how the method is called? Is there an implicit await somewhere?

With the _ keyword its assigning the output of DoAsyncPing() to _ as a Task . In that case there is no execution yet its just a task.

Without the _ = then the function is called and the compiler is warning you that the call is not awaited. So the first method is assignment and the second is execution

About your code, _ contains Task.

If you don't put await execution of existing method will continue regardless of your async method's completion status

if you need to wait for some async operation to be completed before continuing the current method you should put await

let's take an example.

  1. You want some counter data from a website you a method for that (Eg public async Task<int> GetCounter() )

Here GetCounter is an async method but you should wait for it before continuing. hence put await.

  1. You want to push +1 counter to the same website now you don't want to know if the website received that or not at that time you can ignore putting await.

If you want to invoke an Async method you will have to return Task instead of void .

Since you're trying to call DoAsyncPing() from Heartbeat :

1.- Convert void Heartbeat(object state) to async Task HeartbeatAsync(object state) .

  • Adding the async statement will allow you to await inside it.

  • Convention says you might need to call awaitable/async methods MethodNameAsync() .

2.- Covering previous requirement, you now would be able to call DoAsyncPing() (I suggest renaming it to DoPingAsync() this way:

public async Task Heartbeat(object state)
{
    // Discard the result
    _ = await DoAsyncPing();
}

Give a try to this Stephen's Cleary post where explains how to work with async and await and why you should avoid async void . In a nutshell: just use async void on events and when you call an async method, everything inside it has to return at least Task .

Hope it helped.

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