I am writing some awaitable methods and I found a lot of way to do so on the internet. So I came here to know what is really happening on each way, and if some ways must be banished.
As far as I know, there is two kind of awaitable methods:
public async Task<Foo> GetFooAsync()
{
var foo = await TrulyGetFooAsync();
// Do stuff with foo
return foo;
}
I did not find any other way to do this and I think it is the right way. Tell me if I am wrong !
And here the problems come in my mind.
For example, I saw this:
public async Task<Foo> GetFooAsync()
{
return await Task.Run(() => TrulyGetFoo());
}
As far as I understand, the async/await keywords are useless and can be avoided to give this:
public Task<Foo> GetFooAsync()
{
return Task.Run(() => TrulyGetFoo());
}
This last example is what I was doing until now. About that, is there a difference between:
Task.Run(() => TrulyGetFoo());
and
Task.Run((Foo)TrulyGetFoo); // I don't know if the cast is required at any time but in my code, it was
???
But I recently found this way:
public Task<Foo> GetFooAsync()
{
TaskCompletionSource<Foo> tcs = new TaskCompletionSource<Foo>();
tcs.SetResult(TrulyGetFoo());
return tcs.Task;
}
If I understood properly, an awaitable method does not always run on another thread ??? My guess is the third example is providing this mecanism (but how ??? I only see synchronous code in the third example), when the examples 1 and 2 will always run on a worker thread ???
May be there is still another ways to write awaitable methods, so let me know about them.
For example, I saw [
Task.Run
wrappers around synchronous code]
This is a bad practice. I have a blog post that explains why Task.Run
should not be used as a method implementation.
As far as I understand, the async/await keywords are useless and can be avoided
Yes, but I don't recommend eliding async
/await
in more complex methods.
I recently found [
TaskCompletionSource<T>
]
As noted in the comments, your code example is still synchronous.
To make it asynchronous, your code should start some operation and return TaskCompletionSource<T>.Task
. Then later, whenever that operation completes, your completion handler should call TaskCompletionSource<T>.SetResult
(or similar method). For an example, see TAP wrappers for EAP or TAP wrappers for WaitHandle
s.
TaskFactory.FromAsync
is also a wrapper around TaskCompletionSource<T>
, and is used for TAP wrappers for APM.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With