You have built a complex calculation algorithm. It takes quite some time to complete and you want to make sure that your application remains responsive. What do you do?
The answer is C. However, can someone please explain why A) is incorrect? Because the question does not say that the complex algorithm is CPU bound. If it was CPU bound, then we will have to use Tasks (a reasoning I don't understand very well too, though I know that tasks do help cause the current thread to get suspended until they complete). Additionally, please explain how to decide when to use async/await, and use Tasks.
async, await, and TaskThe await keyword waits for the async method until it returns a value. So the main application thread stops there until it receives a return value. The Task class represents an asynchronous operation and Task<TResult> generic class represents an operation that can return a value.
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
No. An await is an "asynchronous wait". The method will wait for it, but the UI thread will not.
The main benefits of asynchronous programming using async / await include the following: Increase the performance and responsiveness of your application, particularly when you have long-running operations that do not require to block the execution.
What do you do?
A. Use async/await.
B. Run the code synchronously.
C. Use Task.Run.
D. Use a BackgroundWorker.
The async/await
feature in C# 5.0 was implemented in order to make asynchronous code "as easy" as writing synchronous code. If you look into WinAPI, you'll see that almost all async endpoints expose a fully async api, meaning there is no thread. Looking further you'll notice that those same endpoints are doing I/O bound operations.
Assuming your algorithm is CPU bound, and is written in a manner which allows effective computation across multiple processors (for example, your algorithm doesn't have any shared state which needs synchronization), you can take advantage of the Task Parallel Library introduced in .NET 4.0. The TPL provides an abstraction over the ThreadPool, which in turn attempts to offload work evenly in a multiprocessor environment.
The await
keyword can be used on any awaitable object, meaning that object implements the GetAwaiter
method. You would want to use await
when you are using an awaitable and want execution to resume when that awaitable is done doing its work. A Task
implements the awaitable pattern and is used to describe a unit of work which will be completed in the future. You can use Task.Run
and await
, when you want to offload a unit of work on a worker thread and you want to return control to the calling method until that work is done.
Another way of dispatching CPU bound work across multiple processors is to use the Parallel
class which exposes Parallel.For
and Parallel.ForEach
.
On a side note, a BackgroundWorker
can also be used to offload work on a background thread, if thats what the person asking the question was after. It is recommended to use the TPL since .NET 4.0 was released.
To conclude, using the Task Parallel Library is the recommended way to offload work to background threads. You may use them in combination with the Parallel
library to maximize the parallelism of your algorithm. After doing so, test your code to make sure the overhead of using multiple threads doesn't outweigh the time it takes to run your algo synchronously.
Edit
As Stephan mentioned in the comment, you may combine both Parallel.ForEach
and Task.Run
to offload a parallel loop inside a background thread:
var task = Task.Run(() => Parallel.ForEach(.. //Loop here));
I suppose "calculation" implies CPU bound algorithm in the absence of other information. If the algorithm is IO bound async/await is not only acceptable but the correct answer.
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