Gigi Mathew
Gigi Mathew

Reputation: 243

How to know my async method is being awaited?

Is it possible to know that my method is being called using 'await' keyword or not?

For example; method MyAsync() would like to know whether its being awaited or not.

public void CallForBackground()
{
    MyAsync();
}

public async void CallAsync()
{
    bool result = await MyAsync();
}

public Task<bool> MyAsync()
{
    return Task.Run(() =>
    {
    //do something endlessly if its being called without 'await', but how do I know the caller is 'await'ing or not?
    //do something only once if its being called with 'await', but how do I know the caller is 'await'ing or not?


    return true;
    });
}

EDITED: Added a scenario where I would like to know whether MyAsync() is being called with or without 'await';

1) Let's say MyAsync() is connecting to a remote server using TCP.

2) MyAsync() is asynchronous and awaitable.

3) Let's say UserA wanted to connect to remote server asynchronously and once completed he/she would like to know whether it was successful or not before continuing his process. Something similar to CallAsync() method implementation.

4) And UserB wants to fire MyAsync() method, without waiting for it to complete. In this case, UserB don't care whether it was connected or not until he sends a message to remote server. Something similar to CallForBackground() method implementation.

So for UserA (awaiting) MyAsync() method will attempt once and return the status. But for UserB (not awaiting), method will keep trying. For this logic, MyAsync() needs to know whether its being awaiting or not. How do we achieve this?

Upvotes: 1

Views: 938

Answers (3)

Harald Coppoolse
Harald Coppoolse

Reputation: 30464

Apparently you want your actions depend on the swiftness of the calling process. If the calling process is really fast it started awaiting before you check if it awaited. If it is a bit slower it hasn't started awaiting yet before you check it.

Are you sure you want to let your functionality depend on the swiftness of the caller?

Wouldn't it be better if you knew whether someone will ever start awaiting for your result or not? In that case the starter of your process could indicate using a parameter whether he will await for your answer in the near future.

If the starter of your process doesn't know yet whether he will wait in the future for your answer, he could use a CancellationToken to cancel your task once he decided never to await for your answer.

For example: - A process of 10 minutes is started. The starter thinks he will start awaiting after, let's say five minutes. Until then he has better things to do. - Before the starter starts awaiting, the operator decides to stop the program. So the starter knows he will never start awaiting. He uses the CancellationToken to signal that he will never await for the result. - The process regularly checks the cancellationToken to see if it is still expected whether there will ever be an await or not.

public async Task<bool> MyAsync(CancellationToken token)
{
    return Task.Run(() =>
    {
        while (!token.IsCancellationRequested)
        {   // we can still expect that in the near future someone will await
            // act accordingly
        }
        else
        {   // we know for sure that no one will await for the result anymore
            // act accordingly
         }
    });
}

Upvotes: 0

svick
svick

Reputation: 244837

How do we achieve this?

You don't*. A method shouldn't behave differently depending on what the user does to its return value. If you want to have two different behaviors, either add a bool parameter to your method, or, even better, have two separate methods for this.


* Actually there is a way to find out whether your method was awaited. But it's quite complicated (it involves using custom awaiters instead of Task) and I don't think it's the right solution here.

Upvotes: 2

MarcinJuraszek
MarcinJuraszek

Reputation: 125630

  1. You should not have async method returning void. Just don't do that, unless you're sure that's what you need (but most likely you don't!).

  2. async is implementation detail which lets you write your method body in easier and more dev-friently way using awaits and make compiler prepare all the necessary callbacks, etc. for you.

  3. You don't have a way to tell what people are doing with Task you're returning.

Upvotes: 6

Related Questions