Skip Skip - 4 years ago 229
C# Question

how and when to fetch return from awaitable(async) method

I am pretty sure, this was answered already and I read many related stuff but somehow I am not getting it to work in my code. Here is the exact code base.

I have this async method in my library, that returns a string upon doing some DB entries:

public class MyLibrary
{
public async Task<string> DoSomethingAsync()
{
return await DoAsync();
}

// some private method, with multiple parameters
private Task<string> DoAsync()
{
return Task.Run(() => Do());
}
}


Now on UI, below resulted a frozen state or deadlock:

var myTask = MyLibraryobject.DoSomethingAsync();
console.Write(myTask.Result);


Since my call is awaitable, I think, UI thread waits for my call to finish its business and populate the result, doesn't it? Or since the call is running on another thread, the task might not yet completed when my cursor hits the line 2. So what now? the cursor will wait till the task gets completed or the line 2 gets executed whenever the task gets completed? sounds synchronous to me..

Also if at all, I want to 'exlicitly' wait till the task gets finished, how do i enforce that? some posts, suggested in doing like below, which gave me the result, but created some more confusion:

var myTask = Task.Run(async () => await MyLibraryobject.DoSomethingAsync());
myTask.Wait();
console.Write(myTask.Result);


What is happening above? why should i create another task and set it to wait? can't I wait for the thread, used by the async method? Again, i am clearly missing some basic stuff here.

Lastly, this is an async call, but the UI thread is waiting for it to be completed thus gives me an impression that it's synchronous. Am I thinking it right? Then what is the main purpose of async methods, which return something, and UI waits for it to complete?

Also what's the difference between a fire-and-forget call being non-async and async? is there any benefit of returning Task, instead of void, for such calls?

I am pretty sure, some broken link that connects all these pieces together in my brain. Can someone explain that to me, please??

Answer Source

Now on UI, below resulted a frozen state or deadlock:

var myTask = MyLibraryobject.DoSomethingAsync();

This is blocking the UI because it is not awaited. You simply need to await an async method

string res = await MyLibraryobject.DoSomethingAsync();

and the above should be placed in the UI inside an async context too.

Edit - reply to comment do "you mean another wrapper async method, which returns Task<string>..."? No,I don't. When I wrote "inside an async context" I meant to add the async keyword to a subscribed event, like a button click, if you are in the code behind or to your delegate command implementation, if you are in a more advanced MVVM implementation of the GUI.

Furthermore, your class library is supposed to do something truly asynchronous, not just starting a task and wrapping it inside a formally async method, like it is your DoAsync.

Edit - in reply to comment "how should avoid" it? If you can't do async all the way, just keep the library and the API sync and unblock the UI by starting a separate thread to call the sync api.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download