I work with C#/VS2012/.Net4.0/Microsoft.Bcl.async NuGet package
After a previously question, I try to use async/await to avoid freezing UI. But each of my test is unsuccessfull.
The main function, which does a heavy work, was like this :
public bool PopulateTV()
{
using (WaitingForm waitingForm=new WaitingForm())
{
waitingForm.Show();
bool boolResult=DoHeavyWork(); //UI is freezing, waitingForm() doesn't show correctly
return boolResult;
}
}
A call to this function is like
if(!PopulateTV())
{
}
I try to implement the async/await
public async Task<bool> populateTV()
{
using (WaitingForm waitingForm=new WaitingForm())
{
Task<bool> func=DoHeavyWork();
bool boolResult=await func;
return boolResult;
}
}
public Task<bool> DoHeavyWork()
{
//do the work
return boolResult;
}
Of course, I get an error in DoHeavyWork
, as I return a bool
and not Task<bool>
. So I change the DoHeavyWork
function :
public async Task<bool> DoHeavyWork()
{
//do the work
return boolResult;
}
This time, no error, but a warning (I use a non english version of VS, so I translate the error/warning message) :
This async method doesn't have an await operator, so it will execute as synchronous.
It's only a warning, but why do I get this message ?
But it's not the big problem. When I call the parent method PopulateTV(), I want to return a bool value (if(!PopulateTV()) ...
And I get an error :
! operator can't be used with 'System.Threading.Tasks.Task'.
Of course. But PopulateTV()
return a bool
(return boolResult;
), even if the method declaration use Task<bool>
.
Where is my error ?
It's
if(!(await PopulateTV()))
. First wait for the result (bool) and later evaluate it.In the other hand, your not that async method is equivalent to code it this way:
async/await
keywords are meant to work as syntactic sugar in order to re-write your task-based asynchronous pattern code into a more readable one.Actually, if your
DoHeavyWork
does something like this:...is almost the same as writing it this way:
You need to understand that
async/await
is just a compiler feature to let you code elegant asynchronous code, but it doesn't mean that the async method must be asynchronous at all. It means that aTask
instance can be awaited withawait
keyword.That is, you can implement methods with asynchronous signatures (i.e.
Task MyMethod() { }
) but fake them returning aTask
generated by aTaskCompletionSource<T>
:...and this can be also simplified using
Task.FromResult<T>(T result)
, as you can check in some of this answer's code snippets.So, why I need to develop my APIs using task-based asynchronous pattern (TAP)?
Because the caller of your methods shouldn't need to know if the method is synchronous or asynchronous. Method's implementation will decide it, but at the same time the caller can work asynchronously if the whole method is actually asynchronous.
If you do the opposite (sync methods), your entire code flow will need to be changed if you decide to implement everything as asynchronous operations: