Does await really does Task.Run() [duplicate] - c#

This question already has answers here:
What's the new C# await feature do? [closed]
(5 answers)
Does await create another thread internally before shifting to the same thread as the caller (for UI application)
(2 answers)
Regarding how Async and Await works c#
(7 answers)
What am I doing wrong with async/await? [closed]
(1 answer)
Closed 5 years ago.
I am still struggling to fully understand async/await approach. Can anyone tell me as in topic does await really does Task.Run behind? Sometimes people doing async metod including await but saw sometimes people do Task.Run without async method. What is the the right way?

No, async await is just made to allow code to run whilst something else is blocking, and it doesn't do Task.Run, or start a new thread.
https://blog.stephencleary.com/2013/11/there-is-no-thread.html is a decent explanation of it.

The async operator simply turns on the use of the await operator in a method. The await operator will work on anything which is awaitable. In .NET, Task and Task<T> are some examples of awaitables.
Task.Run returns Task and Task.Run<T> returns Task<T> and as I said they are both awaitable so you can await on them.
You can even write your own awaitable type if you want: You just have to make sure to satisfy the requirements of what is considered an awaitable. An awaitable needs to provide an implementation for GetAwaiter and that's it. Here is an awaitable example:
public struct SimpleInt32Awaitable
{
public SimpleInt32Awaiter GetAwaiter()
{
return new SimpleInt32Awaiter();
}
}
public struct SimpleInt32Awaiter
{
public bool IsCompleted { get { return true; } }
public void OnCompleted(Action continuation)
{
}
public int GetResult()
{
return 5;
}
}
And now you can do this:
// Within some other class
static async void SimpleWaitAsync()
{
SimpleInt32Awaitable awaitable = new SimpleInt32Awaitable();
int result = await awaitable;
}

does await really does Task.Run behind?
Others have already linked to one of Cleary's many excellent blog posts on C# concurrency, There Is No Thread.
No, it doesn't use Task.Run behind the scenes.
await is useful for more than just Task.Run. It's for running code after something has completed. That something could be a computation task created with Task.Run, but it could also be, say, data-retrieval, such as with ReadLineAsync. Task is the class used to model all of those somethings.
Task.Run is used to queue work to run on the thread-pool. This is appropriate when writing CPU-bound code, but you shouldn't use Task.Run when dealing with IO-bound operations. In that case, your asynchronous code (perhaps using async/await) should make use of asynchronous IO methods such as WriteLineAsync and the aforementioned ReadLineAsync.
It's an anti-pattern to use Task.Run to run blocking code on a worker thread. You never want to do that, even if it does, say, unblock your GUI thread.
Sometimes people doing async metod including await but saw sometimes people do Task.Run without async method. What is the the right way?
You can indeed create a Task using Task.Run and just let it run, without using await or ContinueWith. These are called 'fire and forget' tasks. They're rarely a good idea. Unlike when await is used, any exception thrown by that task will be lost.
This is explained by -- you guessed it -- Stephen Cleary, in this StackOverflow answer.

There are cases where you are restricted from using async and await - this is, generally, why you will sometimes see Task.Run used instead - this allows you to utilize async code in a synchronous method.
An example of where this is necessary is when using MVC with Child Actions - the framework does not support async child actions, so you must call async code using Task.Run.

Related

Does awaiting a non-async method that returns Task<TResult> release a thread back to the thread pool? [duplicate]

This question already has answers here:
What happens when awaiting on already-completed task?
(4 answers)
Closed 26 days ago.
I'm still figuring out how the async/await works in C#.
If I have a .NET web API application with the following method in my Controller.cs:
[HttpGet("Foo1")]
public async Task<ActionResult<int>> Foo1()
{
return await Foo2();
}
And the following Foo2() function:
public Task<int> Foo2()
int a;
//do some work with a that takes a long time
return Task.FromResult(a);
}
When I receive an HTTP request for the Foo1 method. Does the
return await Foo2(); inside the Controller.cs release the thread until the whole Foo2() function is completed, and is this the correct way of using await/async inside the Web API?
Yes in case if Foo2 is "truly" async and no in your current case (assuming Foo1 actually calls Foo2 and not itself) - state machine implemented by compiler will not actually "await" a finished task and will continue synchronous execution.
Also check out great Eliding Async and Await article by Stephen Cleary.
First I'm going to assume you meant to call Foo2, not Foo1, as the latter results in a stack overflow from infinite recursion.
release the thread until the whole Foo2() function is completed
Every time someone mentions threads in relation to tasks, it raises the hair on the back of my neck. There's literally no thread switching in your code, async or not. And in general tasks have nothing to do with threads.
As to your question, in your example Foo2 isn't going to be generated as an async function but as a normal synchronous function. You'll get regular old imperative code as if there were no async code involved at all.
Foo2() does not look like a real async task method its return Task.FromResult(a); faking the task. so answer is just returning by using Task.FromResult(a); and awaiting a method which does not do anything asynchronous does not make any sense. also please note async programing is not a multithreading programing.

How to execute async method synchronously? [duplicate]

This question already has answers here:
How to cancel a Task in await?
(4 answers)
Closed 2 years ago.
As far as I understand, when you want to wait until async method is completed, you have to use await. Otherwise, it's thread will be detached and you'll never hear back from it again. But when you use await, you then have to make the enclosing method async as well (Why though?). That means, you have to use async-await all the way up the call stack. That also means, you can't await-async in constructors.
async Task<int> Boo()
{
return 1;
}
async Task Far()
{
int res = await Boo();
}
Is there a way to stop this infestation? Meaning, how to execute Boo synchronously and get the result, without having to make Far async ?
EDIT:
Does this answer your question? How to cancel a Task in await?
No, I need to get task done, not cancel it.
That also means, you can't await-async in constructors. - why would you want to?
I really don't, but it looks like I have to.
Task.Result is only the answer if you like deadlocks. Why are you trying so hard to avoid async/await?
the project is huge
for some external methods there are no reason to run them async, though they declared as such
using results of async operations in constructors
"you then have to make the enclosing method async as well" - no. you can wait for the result synchronously by accessing Task.Result
Using Task.Result looks like the answer, but right now I'm unable to compile with it. Supposedly, RunSynchronously() should also be able to solve problem?
because you don't want half-baked objects if you can help it.
Sure, I don't. Ideally, I want to synchronously get the result of external method, marked async and finish object initialization.
Don't do work in constructors
Good point, but I just can't help myself.
RESOLUTION:
Seems like .GetAwaiter().GetResult(); was just enough to do the trick for me. I would consider this an answer, if the question was not marked duplicate.
I think it's a better to approach to use a static method that plays the role of a factory that create instances of your class in an async fashion using a private constructor:
Let me illustrate that using some code
public class MyWorker
{
public IList<TData> Data { get; set; }
//static async method that behave like a constructor
async public static Task<MyWorker> CreateAsync()
{
var data= await FetchDataAsync();
return new MyWorker(data);
}
// private constructor called by the async method
private MyWorker (IList<TData> data)
{
this.Data = data;
}
}
//..
var worker = await MyWorker.CreateAsync();
this way is less error-prone since you instantiate your class in one line of code (LOC) and you don't need to do that using 2 LOC (one for the instance, one for calling the async method which you or someone else might forget to call).

Why use async when I have to use await?

I've been stuck on this question for a while and haven't really found any useful clarification as to why this is.
If I have an async method like:
public async Task<bool> MyMethod()
{
// Some logic
return true;
}
public async void MyMethod2()
{
var status = MyMethod(); // Visual studio green lines this and recommends using await
}
If I use await here, what's the point of the asynchronous method? Doesn't it make the async useless that VS is telling me to call await? Does that not defeat the purpose of offloading a task to a thread without waiting for it to finish?
Does that not defeat the purpose of offloading a task to a thread without waiting for it to finish?
Yes, of course. But that's not the purpose of await/async. The purpose is to allow you to write synchronous code that uses asynchronous operations without wasting threads, or more generally, to give the caller a measure of control over the more or less asynchronous operations.
The basic idea is that as long as you use await and async properly, the whole operation will appear to be synchronous. This is usually a good thing, because most of the things you do are synchronous - say, you don't want to create a user before you request the user name. So you'd do something like this:
var name = await GetNameAsync();
var user = await RemoteService.CreateUserAsync(name);
The two operations are synchronous with respect to each other; the second doesn't (and cannot!) happen before the first. But they aren't (necessarily) synchronous with respect to their caller. A typical example is a Windows Forms application. Imagine you have a button, and the click handler contains the code above - all the code runs on the UI thread, but at the same time, while you're awaiting, the UI thread is free to do other tasks (similar to using Application.DoEvents until the operation completes).
Synchronous code is easier to write and understand, so this allows you to get most of the benefits of asynchronous operations without making your code harder to understand. And you don't lose the ability to do things asynchronously, since Task itself is just a promise, and you don't always have to await it right away. Imagine that GetNameAsync takes a lot of time, but at the same time, you have some CPU work to do before it's done:
var nameTask = GetNameAsync();
for (int i = 0; i < 100; i++) Thread.Sleep(100); // Important busy-work!
var name = await nameTask;
var user = await RemoteService.CreateUserAsync(name);
And now your code is still beautifuly synchronous - await is the synchronization point - while you can do other things in parallel with the asynchronous operations. Another typical example would be firing off multiple asynchronous requests in parallel but keeping the code synchronous with the completion of all of the requests:
var tasks = urls.Select(i => httpClient.GetAsync(i)).ToArray();
await Task.WhenAll(tasks);
The tasks are asynchronous in respect to each other, but not their caller, which is still beautifuly synchronous.
I've made a (incomplete) networking sample that uses await in just this way. The basic idea is that while most of the code is logically synchronous (there's a protocol to be followed - ask for login->verify login->read loop...; you can even see the part where multiple tasks are awaited in parallel), you only use a thread when you actually have CPU work to do. Await makes this almost trivial - doing the same thing with continuations or the old Begin/End async model would be much more painful, especially with respect to error handling. Await makes it look very clean.
If I use await here, what's the point of the asynchronous method?
await does not block thread. MyMethod2 will run synchronously until it reaches await expression. Then MyMethod2 will be suspended until awaited task (MyMethod) is complete. While MyMethod is not completed control will return to caller of MyMethod2. That's the point of await - caller will continue doing it's job.
Doesn't it make the async useless that VS is telling me to call await?
async is just a flag which means 'somewhere in the method you have one or more await'.
Does that not defeat the purpose of offloading a task to a thread
without waiting for it to finish?
As described above, you don't have to wait for task to finish. Nothing is blocked here.
NOTE: To follow framework naming standards I suggest you to add Async suffix to asynchronous method names.
An async method is not automatically executed on a different thread. Actually, the opposite is true: an async method is always executed in the calling thread. async means that this is a method that can yield to an asynchronous operation. That means it can return control to the caller while waiting for the other execution to complete. So asnync methods are a way to wait for other asynchronoous operations.
Since you are doing nothing to wait for in MyMethod2, async makes no sense here, so your compiler warns you.
Interestingly, the team that implemented async methods has acknowledged that marking a method async is not really necessary, since it would be enough to just use await in the method body for the compiler to recognize it as async. The requirement of using the async keyword has been added to avoid breaking changes to existing code that uses await as a variable name.

Always use the 'async' and 'await' keywords in asynchronous methods in a library?

Summary: In a library method, when should I use the async and await keywords instead of returning a Task directly?
I believe my question is related to this one. However, that question is about .NET 4.0 and the TPL, while I'm using .NET 4.6 with the async and await keywords. So, I think my question might get different answers because these keywords didn't exist when the linked question was answered.
Explanation: I'm writing a simple wrapper for an external WCF service and the wrapper makes multiple SendAsync calls. Now I think that each wrapper method should just return a Task<> directly without being awaited. My understanding is that async/await should be used on the application layer, and not within a library.
So, for example, here is the approach that I think I should take for each wrapper method:
private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return _service.SendAsync(request);
}
But on the Internet, I found several posts that use this approach instead:
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return await _service.SendAsync(request).ConfigureAwait(false);
}
And here is another example that I found on technet:
async Task PutTaskDelay()
{
await Task.Delay(5000);
}
private async void btnTaskDelay_Click(object sender, EventArgs e)
{
await PutTaskDelay();
MessageBox.Show("I am back");
}
So, when should I use the second approach (the one that includes the async and await keywords)? Why not just return a whole Task without making PutTaskDelay async? I think that I should return Task directly whenever it is possible, and use async/await to get a final result in the application layer only. Am I right? If not, what is the difference between the two approaches that I show here?
My concern: When the async and await keywords are used, it seems that it just provides additional work to the compiler without any benefit.
Should I use async await in library?
It all depends. If you're going to take advantage of the asynchronous programming paradigm, then the answer is "yes," the async and await keywords are needed most of the time. More than likely, you will find yourself needing to use async/await. That is because in most situations it would be difficult to use only Task and Task<T> as you will more than likely need to reason about the results of the async operations that you invoke.
Additionally, based on your question it seems as though you may have some confusion about the keywords themselves and how they relate to the Task and Task<T> types. Allow me to clarify this for you.
The async keyword allows a method to use the await keyword. The best practice is to have all async methods return either Task or Task<T> unless you are unable to (for example, a button click event handler as you demonstrated above).
Methods that return Task or Task<T> represent asynchronous operations. When you are in a library it is suggested to always use .ConfigureAwait(false) for reasons detailed here. Additionally, I always point people to this detailed article on the subject.
To differentiate the two approaches in your question:
The method below returns a Task<SignResponse>. This is an async operation that represents the work to sign in. The method can be awaited by the caller to get SignResponse.
private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return _service.SignAsync(request);
}
Likewise, this version does the same thing...except that the async/await keywords are not needed. The reason they are not needed is that the method itself does not need to use SignResponse and therefore it could simply return Task<SignResponse> as shown above. And as you indicated in your question, there is indeed a penalty when you use the async/await keywords when they are not needed. Doing so adds an extra state machine step as the result is yielded, since its awaited.
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
return await _service.SignAsync(request).ConfigureAwait(false);
}
Finally, if you needed to reason about the response, you could use the aforementioned keywords to do so like this:
private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
var result = await _service.SignAsync(request).ConfigureAwait(false);
if (result.SomeProperty == SomethingWeCareToCheck)
{
_log.Log("Wow, this was un-expected...");
}
return result;
}
Don't take my word for it, because I never understood async/await that well, but what bothered me most about the idea was that all methods using async had to be marked as async as well, which annoyed me to no end.
I guess in a library giving people the option to choose how to use the methods is a good thing, so you should use async, however I always found it more clear to explicitly use the Tasks directly.

Write your own async method

I would like to know how to write your own async methods the "correct" way.
I have seen many many posts explaining the async/await pattern like this:
http://msdn.microsoft.com/en-us/library/hh191443.aspx
// Three things to note in the signature:
// - The method has an async modifier.
// - The return type is Task or Task<T>. (See "Return Types" section.)
// Here, it is Task<int> because the return statement returns an integer.
// - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();
// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;
// The return statement specifies an integer result.
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}
private void DoIndependentWork()
{
resultsTextBox.Text += "Working........\r\n";
}
This works great for any .NET Method that already implements this functionality like
System.IO opertions
DataBase opertions
Network related operations (downloading, uploading...)
But what if I want to write my own method that takes quite some time to complete where there just is no Method I can use and the heavy load is in the DoIndependentWork method of the above example?
In this method I could do:
String manipulations
Calculations
Handling my own objects
Aggregating, comparing, filtering, grouping, handling stuff
List operations, adding, removing, coping
Again I have stumbled across many many posts where people just do the following (again taking the above example):
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
await DoIndependentWork();
string urlContents = await getStringTask;
return urlContents.Length;
}
private Task DoIndependentWork()
{
return Task.Run(() => {
//String manipulations
//Calculations
//Handling my own objects
//Aggregating, comparing, filtering, grouping, handling stuff
//List operations, adding, removing, coping
});
}
You may notice that the changes are that DoIndependentWork now returns a Task and in the AccessTheWebAsync task the method got an await.
The heavy load operations are now capsulated inside a Task.Run(), is this all it takes?
If that's all it takes is the only thing I need to do to provide async Method for every single method in my library the following:
public class FooMagic
{
public void DoSomeMagic()
{
//Do some synchron magic...
}
public Task DoSomeMagicAsync()
{
//Do some async magic... ?!?
return Task.Run(() => { DoSomeMagic(); });
}
}
Would be nice if you could explain it to me since even a high voted question like this:
How to write simple async method? only explains it with already existing methods and just using asyn/await pattern like this comment of the mentioned question brings it to the point:
How to write simple async method?
Actual Answer
You do that using TaskCompletionSource, which has a Promise Task that doesn't execute any code and only:
"Represents the producer side of a Task unbound to a delegate, providing access to the consumer side through the Task property."
You return that task to the caller when you start the asynchronous operation and you set the result (or exception/cancellation) when you end it. Making sure the operation is really asynchronous is on you.
Here is a good example of this kind of root of all async method in Stephen Toub's AsyncManualResetEvent implementation:
class AsyncManualResetEvent
{
private volatile TaskCompletionSource<bool> _tcs = new TaskCompletionSource<bool>();
public Task WaitAsync() { return _tcs.Task; }
public void Set() { _tcs.TrySetResult(true); }
public void Reset()
{
while (true)
{
var tcs = _tcs;
if (!tcs.Task.IsCompleted ||
Interlocked.CompareExchange(ref _tcs, new TaskCompletionSource<bool>(), tcs) == tcs)
return;
}
}
}
Background
There are basically two reasons to use async-await:
Improved scalability: When you have I/O intensive work (or other inherently asynchronous operations), you can call it asynchronously and so you release the calling thread and it's capable of doing other work in the mean time.
Offloading: When you have CPU intensive work, you can call it asynchronously, which moves the work off of one thread to another (mostly used for GUI threads).
So most of the .Net framework's asynchronous calls support async out of the box and for offloading you use Task.Run (as in your example). The only case where you actually need to implement async yourself is when you create a new asynchronous call (I/O or async synchronization constructs for example).
These cases are extremely rare, which is why you mostly find answers that
"Only explains it with already existing methods and just using async/await pattern"
You can go deeper in The Nature of TaskCompletionSource
Would be nice if you could explain it to me: How to write simple async
method?
First, we need to understand what an async method means. When one exposes an async method to the end user consuming the async method, you're telling him: "Listen, this method will return to you quickly with a promise of completing sometime in the near future". That is what you're guaranteeing to your users.
Now, we need to understand how Task makes this "promise" possible. As you ask in your question, why simply adding a Task.Run inside my method makes it valid to be awaited using the await keyword?
A Task implements the GetAwaiter pattern, meaning it returns an object called an awaiter (Its actually called TaskAwaiter). The TaskAwaiter object implements either INotifyCompletion or ICriticalNotifyCompletion interfaces, exposing a OnCompleted method.
All these goodies are in turn used by the compiler once the await keyword is used. The compiler will make sure that at design time, your object implements GetAwaiter, and in turn use that to compile the code into a state machine, which will enable your program to yield control back to the caller once awaited, and resume when that work is completed.
Now, there are some guidelines to follow. A true async method doesn't use extra threads behind the scenes to do its job (Stephan Cleary explains this wonderfully in There Is No Thread), meaning that exposing a method which uses Task.Run inside is a bit misleading to the consumers of your api, because they will assume no extra threading involved in your task. What you should do is expose your API synchronously, and let the user offload it using Task.Run himself, controlling the flow of execution.
async methods are primarily used for I/O Bound operations, since these naturally don't need any threads to be consumed while the IO operation is executing, and that is why we see them alot in classes responsible for doing IO operations, such as hard drive calls, network calls, etc.
I suggest reading the Parallel PFX teams article Should I expose asynchronous wrappers for synchronous methods? which talks exactly about what you're trying to do and why it isn't recommended.
TL;DR:
Task.Run() is what you want, but be careful about hiding it in your library.
I could be wrong, but you might be looking for guidance on getting CPU-Bound code to run asynchronously [by Stephen Cleary]. I've had trouble finding this too, and I think the reason it's so difficult is that's kinda not what you're supposed to do for a library - kinda...
Article
The linked article is a good read (5-15 minutes, depending) that goes into a decent amount of detail about the hows and whys of using Task.Run() as part of an API vs using it to not block a UI thread - and distinguishes between two "types" of long-running process that people like to run asynchronously:
CPU-bound process (one that is crunching / actually working and needs a separate thread to do its work)
Truly asynchronous operation (sometimes called IO-bound - one that is doing a few things here and there with a bunch of waiting time in between actions and would be better off not hogging a thread while it's sitting there doing nothing).
The article touches on the use of API functions in various contexts, and explains whether the associated architectures "prefer" sync or async methods, and how an API with sync and async method signatures "looks" to a developer.
Answer
The last section "OK, enough about the wrong solutions? How do we fix this the right way???" goes into what I think you're asking about, ending with this:
Conclusion: do not use Task.Run in the implementation of the method; instead, use Task.Run to call the method.
Basically, Task.Run() 'hogs' a thread, and is thus the thing to use for CPU-bound work, but it comes down to where it's used. When you're trying to do something that requires a lot of work and you don't want to block the UI Thread, use Task.Run() to run the hard-work function directly (that is, in the event handler or your UI based code):
class MyService
{
public int CalculateMandelbrot()
{
// Tons of work to do in here!
for (int i = 0; i != 10000000; ++i)
;
return 42;
}
}
...
private async void MyButton_Click(object sender, EventArgs e)
{
await Task.Run(() => myService.CalculateMandelbrot());
}
But... don't hide your Task.Run() in an API function suffixed -Async if it is a CPU-bound function, as basically every -Async function is truly asynchronous, and not CPU-bound.
// Warning: bad code!
class MyService
{
public int CalculateMandelbrot()
{
// Tons of work to do in here!
for (int i = 0; i != 10000000; ++i)
;
return 42;
}
public Task<int> CalculateMandelbrotAsync()
{
return Task.Run(() => CalculateMandelbrot());
}
}
In other words, don't call a CPU-bound function -Async, because users will assume it is IO-bound - just call it asynchronously using Task.Run(), and let other users do the same when they feel it's appropriate. Alternately, name it something else that makes sense to you (maybe BeginAsyncIndependentWork() or StartIndependentWorkTask()).

Categories