5

What is the best practice when returning the following Task:

public async Task<Command> BuildCommunicationCommand

As an object:

public Command BuildCommand

I have the following:

 public Command BuildCommand()
    {
        return BuildCommunicationCommand().GetAwaiter().GetResult();
    }

But have been told to try and avoid this and that I should await the Task so we do not block the UI thread. I think the best way to do this is to make the BuildCommand method async and anything else that calls it. This would be a massive change and is not really required for other classes which use the BuildCommand. I do not want to cause a block by using .Result so have read its best to use ConfigureAwait(false) in this case:

 public Command BuildCommand()
        {
            var Command = BuildCommunicationCommand().ConfigureAwait(false);

            return Command.GetAwaiter().GetResult();
        }

Can I use ConfigureAwait(false) to wait for the process to finish and then call .GetAwaiter().GetResult() to return it as the object Command?

This is my first time working with async tasks so if any of the above is complete rubbish I am sorry!

4
  • 4
    make the BuildCommand method async and anything else that calls it Yes, that is the only surefire way to do this. async code is like a virus, once you start with it, it spreads across your entire codebase. Commented Aug 15, 2018 at 10:30
  • out of curiosity, is this Unity code? Commented Aug 15, 2018 at 12:05
  • It is not unity code Commented Aug 15, 2018 at 12:25
  • despite what other people here "think" the ConfigureAwait(false) example you provided is the correct way to deal with this. If people researched the framework implementation code they would see why. that said, going synchronous should be avoided if possible, but let's be honest it is not always possible, and occasionally you have to use a performance-damaging feature like ConfigureAwait(false). Commented Feb 6, 2021 at 22:20

1 Answer 1

6

You can wrap the call to your async method in another method that waits for the task to complete and then returns the result. Of course that blocks the thread that calls GetData. But it gets rid of the async 'virus'. Something like this:

 private string GetData()
 {
     var task = GetDataAsync();
     task.Wait();
     return task.Result;
 }
 private async Task<string> GetDataAsync()
 {
     return "Hello";
 }

You're asking after best practices though, and that is to change everything to async as needed.

Sign up to request clarification or add additional context in comments.

5 Comments

Does this still cause a slight block on the UI thread though? Thanks for the fast reponse
I don't think task.Wait(); is needed. task.Result will also block
If you call it from the UI thread, then yes - it'll block the UI thread. It turns an asynchronous method into a synchronous one. Your issue - as I understand it is that your current method signature is synchronous and changing it is a lot of work. I don't think that you can make it asynchronous without changing the method signature. And then you need to change the way it's called.
I guess it looks like my only options are to either block or make the BuildCommand method asynchronous and everything that calls it asynchronous. Thank you for you help I will mark this as the answer!
this code has a chance to deadlock if called from the STA/UI thread of an application. You actually should use ConfigureAwait(false) in this case (and really no other!) because it will disregard the assigned TaskScheduler and push the operation into a ThreadPool thread (check the framework implementation code and you will see this.) That's precisely what ConfigureAwait(false) is for. You can then safely await the code on an STA/UI/main thread without it resulting in a deadlock (ie. TPL will "convoy" if executing from an STA/UI/main thread as it cannot resume on the calling thread.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.