await and async blocking the UI - c#

I wrote a little winforms application that search for files on the disk (what file is not that important for the sake of the question). the problem is the that it can be even 100,000 files or so. so this operation takes time.
What I want to achieve is to do the search operation as an async operation and not to block the UI thread so the form won't get stuck.
I can do this with the backgroundWorker but for some reason not with the async\await mechanism.
Here is my code:
private async void button_FindFiles_Click(object sender, EventArgs e)
{
await SearchFilesUtil.SearchPnrFilesAsync(this.textBox_mainDirectory.Text);
MessageBox.Show("After SearchPnrFilesAsync");
}
public async static Task SearchPnrFilesAsync(string mainDir)
{
foreach (string file in Directory.EnumerateFiles(mainDir, ".xml", SearchOption.AllDirectories))
{
var fileContenet = File.ReadAllText(file);
var path = Path.Combine(#"C:\CopyFileHere", Path.GetFileName(file));
using (StreamWriter sw = new StreamWriter(path))
{
await sw.WriteAsync(fileContenet);
}
}
}
Why is the UI thread get stuck and not displaying the MessageBox immediately?
what am I missing ?

The fact of marking SearchPnrFilesAsync with async keyword itself doesn't magically starts execution ot this method asynchronously in separate task.
In fact, all of the code in SearchPnrFilesAsync except sw.WriteAsync executes in UI thread thus blocking it.
If you need to execute your whole method in separate task, you can do it by wrapping like:
public async static Task SearchPnrFilesAsync(string mainDir)
{
await Task.Run(() => your_code_here);
}

Why does the UI thread get stuck?
Probably because you have some blocking work done on the UI thread, such as reading a file.
Why is my MessageBox not displayed immediately?
Because that is not how async works. When you await a method, it asynchronously yields control to the caller until the operation is done. When the first await is hit, you start reading files from disk and copying them. await does not mean "execute this on a different thread and continue".
What you probably want to do is use an asynchronous reading mechanism instead of the blocking File.ReadAllText. You can do this using StreamReader:
public static async Task SearchPnrFilesAsync(string mainDir)
{
foreach (string file in Directory.EnumerateFiles(mainDir, ".xml",
SearchOption.AllDirectories))
{
var path = Path.Combine(#"C:\CopyFileHere", Path.GetFileName(file));
using (var reader = File.OpenRead(file))
using (var writer = File.OpenWrite(path))
{
await reader.CopyToAsync(writer);
}
}
}

Why is the UI thread get stuck
I've tested the code you posted doesn't make UI blocked.
When SearchPnrFilesAsync running, I was able to resize the window and click the button as well.
Did you think it was blocked because it didn't show the "After SearchPnrFilesAsync" message? If Something I wrong, please let me know.
not displaying the MessageBox immediately
The await keyword inside the button_FindFiles_Click function asynchronously waits for the SearchFilesUtil.SearchPnrFilesAsync function to finish.
That's why "After SearchPnrFilesAsync" message doesn't pop up as soon as the button is clicked.
If you want the SearchFilesUtil.SearchPnrFilesAsync function to be executed as soon as you click the button
and immediately you want to check the message, you can call the method without await keyword.
SearchFilesUtil.SearchPnrFilesAsync(this.textBox_mainDirectory.Text);
When you don't use await on a function that returns a Task, you'll get a "warning".
In this case, use discards feature and the warning will disappear. (With C# 7)
_ = SearchFilesUtil.SearchPnrFilesAsync(this.textBox_mainDirectory.Text);
If you want to know more about it, please check out this link (
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/functional/discards)

Related

How can i run an await inside of a thread [duplicate]

From my understanding one of the main things that async and await do is to make code easy to write and read - but is using them equal to spawning background threads to perform long duration logic?
I'm currently trying out the most basic example. I've added some comments inline. Can you clarify it for me?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
When using async and await the compiler generates a state machine in the background.
Here's an example on which I hope I can explain some of the high-level details that are going on:
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
OK, so what happens here:
Task<int> longRunningTask = LongRunningOperationAsync(); starts executing LongRunningOperation
Independent work is done on let's assume the Main Thread (Thread ID = 1) then await longRunningTask is reached.
Now, if the longRunningTask hasn't finished and it is still running, MyMethodAsync() will return to its calling method, thus the main thread doesn't get blocked. When the longRunningTask is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync() in its previous context and continue execution (in this case printing the result to the console).
A second case would be that the longRunningTask has already finished its execution and the result is available. When reaching the await longRunningTask we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's a Task.Delay(1000) involved.
From my understanding one of the main things that async and await do is to make code easy to write and read.
They're to make asynchronous code easy to write and read, yes.
Is it the same thing as spawning background threads to perform long duration logic?
Not at all.
// I don't understand why this method must be marked as 'async'.
The async keyword enables the await keyword. So any method using await must be marked async.
// This line is reached after the 5 seconds sleep from DoSomethingAsync() method. Shouldn't it be reached immediately?
No, because async methods are not run on another thread by default.
// Is this executed on a background thread?
No.
You may find my async/await intro helpful. The official MSDN docs are also unusually good (particularly the TAP section), and the async team put out an excellent FAQ.
Explanation
Here is a quick example of async/await at a high level. There are a lot more details to consider beyond this.
Note: Task.Delay(1000) simulates doing work for 1 second. I think it's best to think of this as waiting for a response from an external resource. Since our code is waiting for a response, the system can set the running task off to the side and come back to it once it's finished. Meanwhile, it can do some other work on that thread.
In the example below, the first block is doing exactly that. It starts all the tasks immediately (the Task.Delay lines) and sets them off to the side. The code will pause on the await a line until the 1 second delay is done before going to the next line. Since b, c, d, and e all started executing at almost the exact same time as a (due to lack of the await), they should finish at roughly the same time in this case.
In the example below, the second block is starting a task and waiting for it to finish (that is what await does) before starting the subsequent tasks. Each iteration of this takes 1 second. The await is pausing the program and waiting for the result before continuing. This is the main difference between the first and second blocks.
Example
Console.WriteLine(DateTime.Now);
// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
var a = Task.Delay(1000);
var b = Task.Delay(1000);
var c = Task.Delay(1000);
var d = Task.Delay(1000);
var e = Task.Delay(1000);
await a;
await b;
await c;
await d;
await e;
}
Console.WriteLine(DateTime.Now);
// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);
OUTPUT:
5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)
Extra info regarding SynchronizationContext
Note: This is where things get a little foggy for me, so if I'm wrong on anything, please correct me and I will update the answer. It's important to have a basic understanding of how this works but you can get by without being an expert on it as long as you never use ConfigureAwait(false), although you will likely lose out on some opportunity for optimization, I assume.
There is one aspect of this which makes the async/await concept somewhat trickier to grasp. That's the fact that in this example, this is all happening on the same thread (or at least what appears to be the same thread in regards to its SynchronizationContext). By default, await will restore the synchronization context of the original thread that it was running on. For example, in ASP.NET you have an HttpContext which is tied to a thread when a request comes in. This context contains things specific to the original Http request such as the original Request object which has things like language, IP address, headers, etc. If you switch threads halfway through processing something, you could potentially end up trying to pull information out of this object on a different HttpContext which could be disastrous. If you know you won't be using the context for anything, you can choose to "not care" about it. This basically allows your code to run on a separate thread without bringing the context around with it.
How do you achieve this? By default, the await a; code actually is making an assumption that you DO want to capture and restore the context:
await a; //Same as the line below
await a.ConfigureAwait(true);
If you want to allow the main code to continue on a new thread without the original context, you simply use false instead of true so it knows it doesn't need to restore the context.
await a.ConfigureAwait(false);
After the program is done being paused, it will continue potentially on an entirely different thread with a different context. This is where the performance improvement would come from -- it could continue on on any available thread without having to restore the original context it started with.
Is this stuff confusing? Hell yeah! Can you figure it out? Probably! Once you have a grasp of the concepts, then move on to Stephen Cleary's explanations which tend to be geared more toward someone with a technical understanding of async/await already.
Further to the other answers, have a look at await (C# Reference)
and more specifically at the example included, it explains your situation a bit
The following Windows Forms example illustrates the use of await in an
async method, WaitAsynchronouslyAsync. Contrast the behavior of that
method with the behavior of WaitSynchronously. Without an await
operator applied to a task, WaitSynchronously runs synchronously
despite the use of the async modifier in its definition and a call to
Thread.Sleep in its body.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
For fastest learning..
Understand method execution flow(with a diagram): 3 mins
Question introspection (learning sake): 1 min
Quickly get through syntax sugar: 5 mins
Share the confusion of a developer : 5 mins
Problem: Quickly change a real-world implementation of normal code to
Async code: 2 mins
Where to Next?
Understand method execution flow(with a diagram): 3 mins
In this image, just focus on #6 (nothing more)
At #6 step, execution ran out of work and stopped. To continue it needs a result from getStringTask(kind of a function). Therefore, it uses an await operator to suspend its progress and give control back(yield) to the caller(of this method we are in). The actual call to getStringTask was made earlier in #2. At #2 a promise was made to return a string result. But when will it return the result? Should we(#1:AccessTheWebAsync) make a 2nd call again? Who gets the result, #2(calling statement) or #6(awaiting statement)?
The external caller of AccessTheWebAsync() also is waiting now. So caller waiting for AccessTheWebAsync, and AccessTheWebAsync is waiting for GetStringAsync at the moment. Interesting thing is AccessTheWebAsync did some work(#4) before waiting perhaps to save time from waiting. The same freedom to multitask is also available for the external caller(and all callers in the chain) and this is the biggest plus of this 'async' thingy! You feel like it is synchronous..or normal but it is not.
#2 and #6 is split so we have the advantage of #4(work while waiting). But we can also do it without splitting. So #2 will be: string urlContents = await client.GetStringAsync("...");. Here we see no advantage but somewhere in the chain one function will be splitting while rest of them call it without splitting. It depends which function/class in the chain you use. This change in behavior from function to function is the most confusing part about this topic.
Remember, the method was already returned(#2), it cannot return again(no second time). So how will the caller know? It is all about Tasks! Task was returned. Task status was waited for (not method, not value). Value will be set in Task. Task status will be set to complete. Caller just monitors Task(#6). So 6# is the answer to where/who gets the result. Further reads for later here.
Question introspection for learning sake: 1 min
Let us adjust the question a bit:
How and When to use async and await Tasks?
Because learning Task automatically covers the other two(and answers your question).
The whole idea is pretty simple. A method can return any data type(double, int, object, etc.) but here we just deny that and force a 'Task' object return! But we still need the returned data(except void), right? That will be set in a standard property inside 'Task' object eg: 'Result' property.
Quickly get through syntax sugar: 5 mins
Original non-async method
internal static int Method(int arg0, int arg1)
{
int result = arg0 + arg1;
IO(); // Do some long running IO.
return result;
}
a brand new Task-ified method to call the above method
internal static Task<int> MethodTask(int arg0, int arg1)
{
Task<int> task = new Task<int>(() => Method(arg0, arg1));
task.Start(); // Hot task (started task) should always be returned.
return task;
}
Did we mention await or async? No. Call the above method and you get a task which you can monitor. You already know what the task returns(or contains).. an integer.
Calling a Task is slightly tricky and that is when the keywords starts to appear. If there was a method calling the original method(non-async) then we need to edit it as given below. Let us call MethodTask()
internal static async Task<int> MethodAsync(int arg0, int arg1)
{
int result = await HelperMethods.MethodTask(arg0, arg1);
return result;
}
Same code above added as image below:
We are 'awaiting' task to be finished. Hence the await(mandatory syntax)
Since we use await, we must use async(mandatory syntax)
MethodAsync with Async as the prefix (coding standard)
await is easy to understand but the remaining two (async,Async) may not be :). Well, it should make a lot more sense to the compiler though.Further reads for later here
So there are 2 parts.
Create 'Task' (only one task and it will be an additional method)
Create syntactic sugar to call the task with await+async(this involves changing existing code if you are converting a non-async method)
Remember, we had an external caller to AccessTheWebAsync() and that caller is not spared either... i.e it needs the same await+async too. And the chain continues(hence this is a breaking change which could affect many classes). It can also be considered a non-breaking change because the original method is still there to be called. Change it's access (or delete and move it inside a task) if you want to impose a breaking change and then the classes will be forced to use Task-method. Anyways, in an async call there will always be a Task at one end and only one.
All okay, but one developer was surprised to see Task
missing...
Share the confusion of a developer: 5 mins
A developer has made a mistake of not implementing Task but it still works! Try to understand the question and just the accepted answer provided here. Hope you have read and fully understood. The summary is that we may not see/implement 'Task' but it is implemented somewhere in a parent/associated class. Likewise in our example calling an already built MethodAsync() is way easier than implementing that method with a Task (MethodTask()) ourself. Most developers find it difficult to get their head around Tasks while converting a code to Asynchronous one.
Tip: Try to find an existing Async implementation (like MethodAsync or ToListAsync) to outsource the difficulty. So we only need to deal with Async and await (which is easy and pretty similar to normal code)
Problem: Quickly change a real-world implementation of normal code to
Async operation: 2 mins
Code line shown below in Data Layer started to break(many places). Because we updated some of our code from .Net framework 4.2.* to .Net core. We had to fix this in 1 hour all over the application!
var myContract = query.Where(c => c.ContractID == _contractID).First();
easypeasy!
We installed EntityFramework nuget package because it has QueryableExtensions. Or in other words it does the Async implementation(task), so we could survive with simple Async and await in code.
namespace = Microsoft.EntityFrameworkCore
calling code line got changed like this
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
Method signature changed from
Contract GetContract(int contractnumber)
to
async Task<Contract> GetContractAsync(int contractnumber)
calling method also got affected: GetContract(123456); was called as GetContractAsync(123456).Result;
Wait! what is that Result? Good catch! GetContractAsync only returns a Task not the value we wanted(Contract). Once the result of an operation is available, it is stored and is returned immediately on subsequent calls to the Result property.
We can also do a time-out implementation with a similar 'Wait()'
TimeSpan ts = TimeSpan.FromMilliseconds(150);
if (! t.Wait(ts))
Console.WriteLine("The timeout interval elapsed.");
We changed it everywhere in 30 minutes!
But the architect told us not to use EntityFramework library just for this! oops! drama! Then we made a custom Task implementation(yuk!). Which you know how. Still easy! ..still yuk..
Where to Next?
There is a wonderful quick video we could watch about Converting Synchronous Calls to Asynchronous in ASP.Net Core, perhaps that is likely the direction one would go after reading this. Or have I explained enough? ;)
Showing the above explanations in action in a simple console program:
class Program
{
static void Main(string[] args)
{
TestAsyncAwaitMethods();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public async static void TestAsyncAwaitMethods()
{
await LongRunningMethod();
}
public static async Task<int> LongRunningMethod()
{
Console.WriteLine("Starting Long Running method...");
await Task.Delay(5000);
Console.WriteLine("End Long Running method...");
return 1;
}
}
And the output is:
Starting Long Running method...
Press any key to exit...
End Long Running method...
Thus,
Main starts the long running method via TestAsyncAwaitMethods. That immediately returns without halting the current thread and we immediately see 'Press any key to exit' message
All this while, the LongRunningMethod is running in the background. Once its completed, another thread from Threadpool picks up this context and displays the final message
Thus, not thread is blocked.
I think you've picked a bad example with System.Threading.Thread.Sleep
Point of an async Task is to let it execute in background without locking the main thread, such as doing a DownloadFileAsync
System.Threading.Thread.Sleep isn't something that is "being done", it just sleeps, and therefore your next line is reached after 5 seconds ...
Read this article, I think it is a great explanation of async and await concept: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Async & Await Simple Explanation
Simple Analogy
A person may wait for their morning train. This is all they are doing as this is their primary task that they are currently performing. (synchronous programming (what you normally do!))
Another person may await their morning train whilst they smoke a cigarette and then drink their coffee. (Asynchronous programming)
What is asynchronous programming?
Asynchronous programming is where a programmer will choose to run some of his code on a separate thread from the main thread of execution and then notify the main thread on it's completion.
What does the async keyword actually do?
Prefixing the async keyword to a method name like
async void DoSomething(){ . . .
allows the programmer to use the await keyword when calling asynchronous tasks. That's all it does.
Why is this important?
In a lot of software systems the main thread is reserved for operations specifically relating to the User Interface. If I am running a very complex recursive algorithm that takes 5 seconds to complete on my computer, but I am running this on the Main Thread (UI thread) When the user tries to click on anything on my application, it will appear to be frozen as my main thread has queued and is currently processing far too many operations. As a result the main thread cannot process the mouse click to run the method from the button click.
When do you use Async and Await?
Use the asynchronous keywords ideally when you are doing anything that doesn't involve the user interface.
So lets say you're writing a program that allows the user to sketch on their mobile phone but every 5 seconds it is going to be checking the weather on the internet.
We should be awaiting the call the polling calls every 5 seconds to the network to get the weather as the user of the application needs to keep interacting with the mobile touch screen to draw pretty pictures.
How do you use Async and Await
Following on from the example above, here is some pseudo code of how to write it:
//ASYNCHRONOUS
//this is called using the await keyword every 5 seconds from a polling timer or something.
async Task CheckWeather()
{
var weather = await GetWeather();
//do something with the weather now you have it
}
async Task<WeatherResult> GetWeather()
{
var weatherJson = await CallToNetworkAddressToGetWeather();
return deserializeJson<weatherJson>(weatherJson);
}
//SYNCHRONOUS
//This method is called whenever the screen is pressed
void ScreenPressed()
{
DrawSketchOnScreen();
}
Additional Notes - Update
I forgot to mention in my original notes that in C# you can only await methods that are wrapped in Tasks. for example you may await this method:
// awaiting this will return a string.
// calling this without await (synchronously) will result in a Task<string> object.
async Task<string> FetchHelloWorld() {..
You cannot await methods that are not tasks like this:
async string FetchHelloWorld() {..
Feel free to review the source code for the Task class here.
Here is a quick console program to make it clear to those who follow. The TaskToDo method is your long running method that you want to make async. Making it run async is done by the TestAsync method. The test loops method just runs through the TaskToDo tasks and runs them async. You can see that in the results because they don't complete in the same order from run to run - they are reporting to the console UI thread when they complete. Simplistic, but I think the simplistic examples bring out the core of the pattern better than more involved examples:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestingAsync
{
class Program
{
static void Main(string[] args)
{
TestLoops();
Console.Read();
}
private static async void TestLoops()
{
for (int i = 0; i < 100; i++)
{
await TestAsync(i);
}
}
private static Task TestAsync(int i)
{
return Task.Run(() => TaskToDo(i));
}
private async static void TaskToDo(int i)
{
await Task.Delay(10);
Console.WriteLine(i);
}
}
}
All the answers here use Task.Delay() or some other built in async function. But here is my example that use none of those async functions:
// Starts counting to a large number and then immediately displays message "I'm counting...".
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
Console.WriteLine("Started asyncTest()");
Task<long> task = asyncTest_count();
Console.WriteLine("Started counting, please wait...");
task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
//Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
Console.WriteLine("Finished counting.");
Console.WriteLine("Press any key to exit program.");
Console.ReadLine();
}
static async Task<long> asyncTest_count()
{
long k = 0;
Console.WriteLine("Started asyncTest_count()");
await Task.Run(() =>
{
long countTo = 100000000;
int prevPercentDone = -1;
for (long i = 0; i <= countTo; i++)
{
int percentDone = (int)(100 * (i / (double)countTo));
if (percentDone != prevPercentDone)
{
prevPercentDone = percentDone;
Console.Write(percentDone.ToString() + "% ");
}
k = i;
}
});
Console.WriteLine("");
Console.WriteLine("Finished asyncTest_count()");
return k;
}
This answer aims to provide some info specific to ASP.NET.
By utilizing async/await in the MVC controller, it is possible to increase thread pool utilization and achieve much better throughput, as explained in the below article,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
In web applications that see a large number of concurrent requests at
start-up or have a bursty load (where concurrency increases suddenly),
making these web service calls asynchronous will increase the
responsiveness of your application. An asynchronous request takes the
same amount of time to process as a synchronous request. For example,
if a request makes a web service call that requires two seconds to
complete, the request takes two seconds whether it is performed
synchronously or asynchronously. However, during an asynchronous call,
a thread is not blocked from responding to other requests while it
waits for the first request to complete. Therefore, asynchronous
requests prevent request queuing and thread pool growth when there are
many concurrent requests that invoke long-running operations.
Async / Await
Actually, Async / Await is a pair of keywords that are just syntactic sugar for creating a callback of an asynchronous task.
Take by example this operation:
public static void DoSomeWork()
{
var task = Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS NOT bubbling up due to the different threads
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// This is the callback
task.ContinueWith((t) => {
// -> Exception is swallowed silently
Console.WriteLine("Completed");
// [RUNS ON WORKER THREAD]
});
}
The code above has several disadvantages. Errors are not passed on and it's hard to read.
But Async and Await come in to help us out:
public async static void DoSomeWork()
{
var result = await Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS bubbling up
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// every thing below is a callback
// (including the calling methods)
Console.WriteLine("Completed");
}
Await calls have to be in Async methods. This has some advantages:
Returns the result of the Task
creates automatically a callback
checks for errors and lets them bubble up in callstack (only up to none-await calls in callstack)
waits for the result
frees up the main thread
runs the callback on the main thread
uses a worker thread from the threadpool for the task
makes the code easy to read
and a lot more
NOTE: Async and Await are used with asynchronous calls not to make these. You have to use Task Libary for this, like Task.Run() .
Here is a comparison between await and none await solutions
This is the none async solution:
public static long DoTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
var task = Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// goes directly further
// WITHOUT waiting until the task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 50 milliseconds
return stopWatch.ElapsedMilliseconds;
}
This is the async method:
public async static Task<long> DoAwaitTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
await Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// Waits until task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 2050 milliseconds
return stopWatch.ElapsedMilliseconds;
}
You can actually call an async method without the await keyword but this means that any Exception here is swallowed in release mode:
public static Stopwatch stopWatch { get; } = new Stopwatch();
static void Main(string[] args)
{
Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
// 2050 (2000 more because of the await)
Console.WriteLine("DoTask: " + DoTask() + " ms");
// 50
Console.ReadKey();
}
Async and Await are not meant for parallel computing. They are used to not block your main thread. When it's about asp.net or Windows applications, blocking your main thread due to a network call is a bad thing. If you do this, your app will get unresponsive or even crash.
Check out MS docs for more examples.
To be honest I still think the best explanation is the one about future and promises on the Wikipedia: http://en.wikipedia.org/wiki/Futures_and_promises
The basic idea is that you have a separate pool of threads that execute tasks asynchronously. When using it. The object does however make the promise that it will execute the operation at some time and give you the result when you request it. This means that it will block when you request the result and hasn't finished, but execute in the thread pool otherwise.
From there you can optimize things: some operations can be implemented async and you can optimize things like file IO and network communication by batching together subsequent requests and/or reordering them. I'm not sure if this is already in the task framework of Microsoft - but if it isn't that would be one of the first things I would add.
You can actually implement the future pattern sort-of with yields in C# 4.0. If you want to know how it works exactly, I can recommend this link that does a decent job: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . However, if you start toying with it yourself, you will notice that you really need language support if you want to do all the cool things -- which is exactly what Microsoft did.
See this fiddle https://dotnetfiddle.net/VhZdLU (and improve it if possible) for running a simple console application which shows usages of Task, Task.WaitAll(), async and await operators in the same program.
This fiddle should clear your execution cycle concept.
Here is the sample code
using System;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met
Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
Console.WriteLine("Now Waiting for Task to be Finished");
Task.WaitAll(a); //Now Waiting
Console.WriteLine("Exiting CommandLine");
}
public static async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperation();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine("Result of LongRunningOperation() is " + result);
}
public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
Console.WriteLine("LongRunningOperation() Started");
await Task.Delay(2000); // 2 second delay
Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
return 1;
}
}
Trace coming from Output Window:
I'd like to give my two cents to this, I'm sorry if any other answer contains what I will explain, I read most of it and haven't find it, but I could have missed something.
I saw a lot of missconceptions and a lot of good explanations, just want to explain async in terms of how it differs from parallel programming, that I believe will make things easier to understand.
When you need to do long computations, processor intensive work, you should opt to use parallel programming, if it's possible, to optimize cores usage. This opens some threads and process things simultaneosly.
Say you have an array of numbers and want to make some expensive long calculation with every and each one of than. Parallel is your friend.
Asyncronous programming is used in a different use case.
It's used to free your thread when you are waiting for something that do not depend on your processor, like IO for example (writing and reading to/from disk), your thread does nothing when you do IO, same thing when you are awaiting for some result from an expensive query to return from DB.
Async methods free your thread when it's waiting for something long to return results. This thread can be used by other parts of your application (in a web app it process other requests, for example) or can return to OS for other use.
When your result is done, the same thread (or another one) is given back to your application to resume processing.
Async programming is not mandatory (but a good practice) in a multithreaded environment like .net, in a web app other threads will respond to new requests, but if you are in a singlethreaded framework like nodejs it's mandatory, because you can't block your only thread, or you won't be able to anwser any other request.
To summarize, long processor intensive calculations will benefit more from parallel programming and long waiting periods that do not depend on your processor, like IO or DB query or a call to some API will benefit more from async programming.
That's why Entity Framework, for example, has an async api to save, list, find, etc...
Remember that async/await is not the same as wait or waitAll, the contexts are different. Async/await release the thread and are asyncronous programming. wait / waitAll blocks all threads (they are not released) to force syncronization in parallel context... different stuff...
Hope this is usefull for someone...
On a higher level:
1) Async keyword enables the await and that's all it does. Async keyword does not run the method in a separate thread. The beginning f async method runs synchronously until it hits await on a time-consuming task.
2) You can await on a method that returns Task or Task of type T. You cannot await on async void method.
3) The moment main thread encounters await on time-consuming task or when the actual work is started, the main thread returns to the caller of the current method.
4) If the main thread sees await on a task that is still executing, it doesn't wait for it and returns to the caller of the current method. In this way, the application remains responsive.
5) Await on processing task, will now execute on a separate thread from the thread pool.
6) When this await task is completed, all the code below it will be executed by the separate thread
Below is the sample code. Execute it and check the thread id
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAwaitDemo
{
class Program
{
public static async void AsynchronousOperation()
{
Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//Task<int> _task = AsyncMethod();
int count = await AsyncMethod();
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//int count = await _task;
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
DependentMethod(count);
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
}
public static async Task<int> AsyncMethod()
{
Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
int count = 0;
await Task.Run(() =>
{
Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
count = 10;
});
Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
return count;
}
public static void DependentMethod(int count)
{
Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
}
static void Main(string[] args)
{
Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
AsynchronousOperation();
Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
}
}
The way I understand it is also, there should be a third term added to the mix: Task.
Async is just a qualifier you put on your method to say it's an asynchronous method.
Task is the return of the async function. It executes asynchronously.
You await a Task. When code execution reaches this line, control jumps out back to caller of your surrounding original function.
If instead, you assign the return of an async function (ie Task) to a variable, when code execution reaches this line, it just continues past that line in the surrounding function while the Task executes asynchronously.
public static void Main(string[] args)
{
string result = DownloadContentAsync().Result;
Console.ReadKey();
}
// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread.
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
using (HttpClient client = new HttpClient())
{
// When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
// If it is already finished, the method continues to run synchronously.
// If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.
// Http request example.
// (In this example I can set the milliseconds after "sleep=")
String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");
Console.WriteLine(result);
// After completing the result response, the state machine will continue to synchronously execute the other processes.
return result;
}
}
The best example is here,enjoy:
is using them equal to spawning background threads to perform long
duration logic?
This article MDSN:Asynchronous Programming with async and await (C#) explains it explicitly:
The async and await keywords don't cause additional threads to be
created. Async methods don't require multithreading because an async
method doesn't run on its own thread. The method runs on the current
synchronization context and uses time on the thread only when the
method is active.
Below is code which reads excel file by opening dialog and then uses async and wait to run asynchronous the code which reads one by one line from excel and binds to grid
namespace EmailBillingRates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
lblProcessing.Text = "";
}
private async void btnReadExcel_Click(object sender, EventArgs e)
{
string filename = OpenFileDialog();
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(filename);
Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
try
{
Task<int> longRunningTask = BindGrid(xlRange);
int result = await longRunningTask;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
//cleanup
// GC.Collect();
//GC.WaitForPendingFinalizers();
//rule of thumb for releasing com objects:
// never use two dots, all COM objects must be referenced and released individually
// ex: [somthing].[something].[something] is bad
//release com objects to fully kill excel process from running in the background
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlWorksheet);
//close and release
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook);
//quit and release
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
}
}
private void btnSendEmail_Click(object sender, EventArgs e)
{
}
private string OpenFileDialog()
{
string filename = "";
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "Excel File Dialog";
fdlg.InitialDirectory = #"c:\";
fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
fdlg.FilterIndex = 2;
fdlg.RestoreDirectory = true;
if (fdlg.ShowDialog() == DialogResult.OK)
{
filename = fdlg.FileName;
}
return filename;
}
private async Task<int> BindGrid(Microsoft.Office.Interop.Excel.Range xlRange)
{
lblProcessing.Text = "Processing File.. Please wait";
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
// dt.Column = colCount;
dataGridView1.ColumnCount = colCount;
dataGridView1.RowCount = rowCount;
for (int i = 1; i <= rowCount; i++)
{
for (int j = 1; j <= colCount; j++)
{
//write the value to the Grid
if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null)
{
await Task.Delay(1);
dataGridView1.Rows[i - 1].Cells[j - 1].Value = xlRange.Cells[i, j].Value2.ToString();
}
}
}
lblProcessing.Text = "";
return 0;
}
}
internal class async
{
}
}
Answering your second question - WHEN to use async - here's a fairly easy approach we use:
Long-running I/O bound task that runs longer than 50ms - use async.
Long-running CPU-bound task - use parallel execution, threads etc.
Explanation: when you're doing I/O work - sending a network request, reading data from disk etc - the actual work is done by "external" silicon (network card, disk controller etc). Once the work is done - the I/O device driver will "ping" the OS back, and the OS will execute your continuation code, callback/etc. Until then the CPU is free to do it's own work (and as a bonus you might also free up a threadpool thread which is a very nice bonus for web app scalability)
P.S. The 50ms threshold is MS's recommendation. Otherwise the overhead added by async (creating the state machine, execution context etc) eats up all the benefits. Can't find the original MS article now, but it's mentioned here too https://www.red-gate.com/simple-talk/dotnet/net-framework/the-overhead-of-asyncawait-in-net-4-5/
The answers here are useful as a general guidance about await/async. They also contain some detail about how await/async is wired. I would like to share some practical experience with you that you should know before using this design pattern.
The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing. On the foreground thread, this is a disaster. The foreground thread carries the burden of constructing your app, including views, view models, initial animations, and whatever else you have boot-strapped with those elements. So when you await the foreground thread, you stop the app. The user waits and waits when nothing appears to happen. This provides a negative user experience.
You can certainly await a background thread using a variety of means:
Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });
// Notice that we do not await the following call,
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}
The complete code for these remarks is at https://github.com/marcusts/xamarin-forms-annoyances. See the solution called AwaitAsyncAntipattern.sln.
The GitHub site also provides links to a more detailed discussion on this topic.
The async is used with a function to makes it into an asynchronous function. The await keyword is used to invoke an asynchronous function synchronously. The await keyword holds the JS engine execution until promise is resolved.
We should use async & await only when we want the result immediately. Maybe the result returned from the function is getting used in the next line.
Follow this blog, It is very well written in simple word
Maybe my insight is relevant. async tells the compiler to treat a function specially, the function is suspendable/resumable, it saves state in some way. await suspends a function, but is also a way to enforce discipline, is restrictive; you need to specify what you are waiting for, you can't just suspend without cause, which is what makes the code more readable and perhaps also more efficient. This opens up another question. Why not await multiple things, why just one at a time? I believe this is because such a pattern established itself and programmers are following the principle of least astonishment. There exists the possibility of ambiguity: are you satisfied with just one of conditions being fulfilled, or do you want all to be fulfilled, perhaps just some of them?

Why do I not need to wrap this async result in a Task? [duplicate]

From my understanding one of the main things that async and await do is to make code easy to write and read - but is using them equal to spawning background threads to perform long duration logic?
I'm currently trying out the most basic example. I've added some comments inline. Can you clarify it for me?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
When using async and await the compiler generates a state machine in the background.
Here's an example on which I hope I can explain some of the high-level details that are going on:
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
OK, so what happens here:
Task<int> longRunningTask = LongRunningOperationAsync(); starts executing LongRunningOperation
Independent work is done on let's assume the Main Thread (Thread ID = 1) then await longRunningTask is reached.
Now, if the longRunningTask hasn't finished and it is still running, MyMethodAsync() will return to its calling method, thus the main thread doesn't get blocked. When the longRunningTask is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync() in its previous context and continue execution (in this case printing the result to the console).
A second case would be that the longRunningTask has already finished its execution and the result is available. When reaching the await longRunningTask we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's a Task.Delay(1000) involved.
From my understanding one of the main things that async and await do is to make code easy to write and read.
They're to make asynchronous code easy to write and read, yes.
Is it the same thing as spawning background threads to perform long duration logic?
Not at all.
// I don't understand why this method must be marked as 'async'.
The async keyword enables the await keyword. So any method using await must be marked async.
// This line is reached after the 5 seconds sleep from DoSomethingAsync() method. Shouldn't it be reached immediately?
No, because async methods are not run on another thread by default.
// Is this executed on a background thread?
No.
You may find my async/await intro helpful. The official MSDN docs are also unusually good (particularly the TAP section), and the async team put out an excellent FAQ.
Explanation
Here is a quick example of async/await at a high level. There are a lot more details to consider beyond this.
Note: Task.Delay(1000) simulates doing work for 1 second. I think it's best to think of this as waiting for a response from an external resource. Since our code is waiting for a response, the system can set the running task off to the side and come back to it once it's finished. Meanwhile, it can do some other work on that thread.
In the example below, the first block is doing exactly that. It starts all the tasks immediately (the Task.Delay lines) and sets them off to the side. The code will pause on the await a line until the 1 second delay is done before going to the next line. Since b, c, d, and e all started executing at almost the exact same time as a (due to lack of the await), they should finish at roughly the same time in this case.
In the example below, the second block is starting a task and waiting for it to finish (that is what await does) before starting the subsequent tasks. Each iteration of this takes 1 second. The await is pausing the program and waiting for the result before continuing. This is the main difference between the first and second blocks.
Example
Console.WriteLine(DateTime.Now);
// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
var a = Task.Delay(1000);
var b = Task.Delay(1000);
var c = Task.Delay(1000);
var d = Task.Delay(1000);
var e = Task.Delay(1000);
await a;
await b;
await c;
await d;
await e;
}
Console.WriteLine(DateTime.Now);
// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);
OUTPUT:
5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)
Extra info regarding SynchronizationContext
Note: This is where things get a little foggy for me, so if I'm wrong on anything, please correct me and I will update the answer. It's important to have a basic understanding of how this works but you can get by without being an expert on it as long as you never use ConfigureAwait(false), although you will likely lose out on some opportunity for optimization, I assume.
There is one aspect of this which makes the async/await concept somewhat trickier to grasp. That's the fact that in this example, this is all happening on the same thread (or at least what appears to be the same thread in regards to its SynchronizationContext). By default, await will restore the synchronization context of the original thread that it was running on. For example, in ASP.NET you have an HttpContext which is tied to a thread when a request comes in. This context contains things specific to the original Http request such as the original Request object which has things like language, IP address, headers, etc. If you switch threads halfway through processing something, you could potentially end up trying to pull information out of this object on a different HttpContext which could be disastrous. If you know you won't be using the context for anything, you can choose to "not care" about it. This basically allows your code to run on a separate thread without bringing the context around with it.
How do you achieve this? By default, the await a; code actually is making an assumption that you DO want to capture and restore the context:
await a; //Same as the line below
await a.ConfigureAwait(true);
If you want to allow the main code to continue on a new thread without the original context, you simply use false instead of true so it knows it doesn't need to restore the context.
await a.ConfigureAwait(false);
After the program is done being paused, it will continue potentially on an entirely different thread with a different context. This is where the performance improvement would come from -- it could continue on on any available thread without having to restore the original context it started with.
Is this stuff confusing? Hell yeah! Can you figure it out? Probably! Once you have a grasp of the concepts, then move on to Stephen Cleary's explanations which tend to be geared more toward someone with a technical understanding of async/await already.
Further to the other answers, have a look at await (C# Reference)
and more specifically at the example included, it explains your situation a bit
The following Windows Forms example illustrates the use of await in an
async method, WaitAsynchronouslyAsync. Contrast the behavior of that
method with the behavior of WaitSynchronously. Without an await
operator applied to a task, WaitSynchronously runs synchronously
despite the use of the async modifier in its definition and a call to
Thread.Sleep in its body.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
For fastest learning..
Understand method execution flow(with a diagram): 3 mins
Question introspection (learning sake): 1 min
Quickly get through syntax sugar: 5 mins
Share the confusion of a developer : 5 mins
Problem: Quickly change a real-world implementation of normal code to
Async code: 2 mins
Where to Next?
Understand method execution flow(with a diagram): 3 mins
In this image, just focus on #6 (nothing more)
At #6 step, execution ran out of work and stopped. To continue it needs a result from getStringTask(kind of a function). Therefore, it uses an await operator to suspend its progress and give control back(yield) to the caller(of this method we are in). The actual call to getStringTask was made earlier in #2. At #2 a promise was made to return a string result. But when will it return the result? Should we(#1:AccessTheWebAsync) make a 2nd call again? Who gets the result, #2(calling statement) or #6(awaiting statement)?
The external caller of AccessTheWebAsync() also is waiting now. So caller waiting for AccessTheWebAsync, and AccessTheWebAsync is waiting for GetStringAsync at the moment. Interesting thing is AccessTheWebAsync did some work(#4) before waiting perhaps to save time from waiting. The same freedom to multitask is also available for the external caller(and all callers in the chain) and this is the biggest plus of this 'async' thingy! You feel like it is synchronous..or normal but it is not.
#2 and #6 is split so we have the advantage of #4(work while waiting). But we can also do it without splitting. So #2 will be: string urlContents = await client.GetStringAsync("...");. Here we see no advantage but somewhere in the chain one function will be splitting while rest of them call it without splitting. It depends which function/class in the chain you use. This change in behavior from function to function is the most confusing part about this topic.
Remember, the method was already returned(#2), it cannot return again(no second time). So how will the caller know? It is all about Tasks! Task was returned. Task status was waited for (not method, not value). Value will be set in Task. Task status will be set to complete. Caller just monitors Task(#6). So 6# is the answer to where/who gets the result. Further reads for later here.
Question introspection for learning sake: 1 min
Let us adjust the question a bit:
How and When to use async and await Tasks?
Because learning Task automatically covers the other two(and answers your question).
The whole idea is pretty simple. A method can return any data type(double, int, object, etc.) but here we just deny that and force a 'Task' object return! But we still need the returned data(except void), right? That will be set in a standard property inside 'Task' object eg: 'Result' property.
Quickly get through syntax sugar: 5 mins
Original non-async method
internal static int Method(int arg0, int arg1)
{
int result = arg0 + arg1;
IO(); // Do some long running IO.
return result;
}
a brand new Task-ified method to call the above method
internal static Task<int> MethodTask(int arg0, int arg1)
{
Task<int> task = new Task<int>(() => Method(arg0, arg1));
task.Start(); // Hot task (started task) should always be returned.
return task;
}
Did we mention await or async? No. Call the above method and you get a task which you can monitor. You already know what the task returns(or contains).. an integer.
Calling a Task is slightly tricky and that is when the keywords starts to appear. If there was a method calling the original method(non-async) then we need to edit it as given below. Let us call MethodTask()
internal static async Task<int> MethodAsync(int arg0, int arg1)
{
int result = await HelperMethods.MethodTask(arg0, arg1);
return result;
}
Same code above added as image below:
We are 'awaiting' task to be finished. Hence the await(mandatory syntax)
Since we use await, we must use async(mandatory syntax)
MethodAsync with Async as the prefix (coding standard)
await is easy to understand but the remaining two (async,Async) may not be :). Well, it should make a lot more sense to the compiler though.Further reads for later here
So there are 2 parts.
Create 'Task' (only one task and it will be an additional method)
Create syntactic sugar to call the task with await+async(this involves changing existing code if you are converting a non-async method)
Remember, we had an external caller to AccessTheWebAsync() and that caller is not spared either... i.e it needs the same await+async too. And the chain continues(hence this is a breaking change which could affect many classes). It can also be considered a non-breaking change because the original method is still there to be called. Change it's access (or delete and move it inside a task) if you want to impose a breaking change and then the classes will be forced to use Task-method. Anyways, in an async call there will always be a Task at one end and only one.
All okay, but one developer was surprised to see Task
missing...
Share the confusion of a developer: 5 mins
A developer has made a mistake of not implementing Task but it still works! Try to understand the question and just the accepted answer provided here. Hope you have read and fully understood. The summary is that we may not see/implement 'Task' but it is implemented somewhere in a parent/associated class. Likewise in our example calling an already built MethodAsync() is way easier than implementing that method with a Task (MethodTask()) ourself. Most developers find it difficult to get their head around Tasks while converting a code to Asynchronous one.
Tip: Try to find an existing Async implementation (like MethodAsync or ToListAsync) to outsource the difficulty. So we only need to deal with Async and await (which is easy and pretty similar to normal code)
Problem: Quickly change a real-world implementation of normal code to
Async operation: 2 mins
Code line shown below in Data Layer started to break(many places). Because we updated some of our code from .Net framework 4.2.* to .Net core. We had to fix this in 1 hour all over the application!
var myContract = query.Where(c => c.ContractID == _contractID).First();
easypeasy!
We installed EntityFramework nuget package because it has QueryableExtensions. Or in other words it does the Async implementation(task), so we could survive with simple Async and await in code.
namespace = Microsoft.EntityFrameworkCore
calling code line got changed like this
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
Method signature changed from
Contract GetContract(int contractnumber)
to
async Task<Contract> GetContractAsync(int contractnumber)
calling method also got affected: GetContract(123456); was called as GetContractAsync(123456).Result;
Wait! what is that Result? Good catch! GetContractAsync only returns a Task not the value we wanted(Contract). Once the result of an operation is available, it is stored and is returned immediately on subsequent calls to the Result property.
We can also do a time-out implementation with a similar 'Wait()'
TimeSpan ts = TimeSpan.FromMilliseconds(150);
if (! t.Wait(ts))
Console.WriteLine("The timeout interval elapsed.");
We changed it everywhere in 30 minutes!
But the architect told us not to use EntityFramework library just for this! oops! drama! Then we made a custom Task implementation(yuk!). Which you know how. Still easy! ..still yuk..
Where to Next?
There is a wonderful quick video we could watch about Converting Synchronous Calls to Asynchronous in ASP.Net Core, perhaps that is likely the direction one would go after reading this. Or have I explained enough? ;)
Showing the above explanations in action in a simple console program:
class Program
{
static void Main(string[] args)
{
TestAsyncAwaitMethods();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public async static void TestAsyncAwaitMethods()
{
await LongRunningMethod();
}
public static async Task<int> LongRunningMethod()
{
Console.WriteLine("Starting Long Running method...");
await Task.Delay(5000);
Console.WriteLine("End Long Running method...");
return 1;
}
}
And the output is:
Starting Long Running method...
Press any key to exit...
End Long Running method...
Thus,
Main starts the long running method via TestAsyncAwaitMethods. That immediately returns without halting the current thread and we immediately see 'Press any key to exit' message
All this while, the LongRunningMethod is running in the background. Once its completed, another thread from Threadpool picks up this context and displays the final message
Thus, not thread is blocked.
I think you've picked a bad example with System.Threading.Thread.Sleep
Point of an async Task is to let it execute in background without locking the main thread, such as doing a DownloadFileAsync
System.Threading.Thread.Sleep isn't something that is "being done", it just sleeps, and therefore your next line is reached after 5 seconds ...
Read this article, I think it is a great explanation of async and await concept: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Async & Await Simple Explanation
Simple Analogy
A person may wait for their morning train. This is all they are doing as this is their primary task that they are currently performing. (synchronous programming (what you normally do!))
Another person may await their morning train whilst they smoke a cigarette and then drink their coffee. (Asynchronous programming)
What is asynchronous programming?
Asynchronous programming is where a programmer will choose to run some of his code on a separate thread from the main thread of execution and then notify the main thread on it's completion.
What does the async keyword actually do?
Prefixing the async keyword to a method name like
async void DoSomething(){ . . .
allows the programmer to use the await keyword when calling asynchronous tasks. That's all it does.
Why is this important?
In a lot of software systems the main thread is reserved for operations specifically relating to the User Interface. If I am running a very complex recursive algorithm that takes 5 seconds to complete on my computer, but I am running this on the Main Thread (UI thread) When the user tries to click on anything on my application, it will appear to be frozen as my main thread has queued and is currently processing far too many operations. As a result the main thread cannot process the mouse click to run the method from the button click.
When do you use Async and Await?
Use the asynchronous keywords ideally when you are doing anything that doesn't involve the user interface.
So lets say you're writing a program that allows the user to sketch on their mobile phone but every 5 seconds it is going to be checking the weather on the internet.
We should be awaiting the call the polling calls every 5 seconds to the network to get the weather as the user of the application needs to keep interacting with the mobile touch screen to draw pretty pictures.
How do you use Async and Await
Following on from the example above, here is some pseudo code of how to write it:
//ASYNCHRONOUS
//this is called using the await keyword every 5 seconds from a polling timer or something.
async Task CheckWeather()
{
var weather = await GetWeather();
//do something with the weather now you have it
}
async Task<WeatherResult> GetWeather()
{
var weatherJson = await CallToNetworkAddressToGetWeather();
return deserializeJson<weatherJson>(weatherJson);
}
//SYNCHRONOUS
//This method is called whenever the screen is pressed
void ScreenPressed()
{
DrawSketchOnScreen();
}
Additional Notes - Update
I forgot to mention in my original notes that in C# you can only await methods that are wrapped in Tasks. for example you may await this method:
// awaiting this will return a string.
// calling this without await (synchronously) will result in a Task<string> object.
async Task<string> FetchHelloWorld() {..
You cannot await methods that are not tasks like this:
async string FetchHelloWorld() {..
Feel free to review the source code for the Task class here.
Here is a quick console program to make it clear to those who follow. The TaskToDo method is your long running method that you want to make async. Making it run async is done by the TestAsync method. The test loops method just runs through the TaskToDo tasks and runs them async. You can see that in the results because they don't complete in the same order from run to run - they are reporting to the console UI thread when they complete. Simplistic, but I think the simplistic examples bring out the core of the pattern better than more involved examples:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestingAsync
{
class Program
{
static void Main(string[] args)
{
TestLoops();
Console.Read();
}
private static async void TestLoops()
{
for (int i = 0; i < 100; i++)
{
await TestAsync(i);
}
}
private static Task TestAsync(int i)
{
return Task.Run(() => TaskToDo(i));
}
private async static void TaskToDo(int i)
{
await Task.Delay(10);
Console.WriteLine(i);
}
}
}
All the answers here use Task.Delay() or some other built in async function. But here is my example that use none of those async functions:
// Starts counting to a large number and then immediately displays message "I'm counting...".
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
Console.WriteLine("Started asyncTest()");
Task<long> task = asyncTest_count();
Console.WriteLine("Started counting, please wait...");
task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
//Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
Console.WriteLine("Finished counting.");
Console.WriteLine("Press any key to exit program.");
Console.ReadLine();
}
static async Task<long> asyncTest_count()
{
long k = 0;
Console.WriteLine("Started asyncTest_count()");
await Task.Run(() =>
{
long countTo = 100000000;
int prevPercentDone = -1;
for (long i = 0; i <= countTo; i++)
{
int percentDone = (int)(100 * (i / (double)countTo));
if (percentDone != prevPercentDone)
{
prevPercentDone = percentDone;
Console.Write(percentDone.ToString() + "% ");
}
k = i;
}
});
Console.WriteLine("");
Console.WriteLine("Finished asyncTest_count()");
return k;
}
This answer aims to provide some info specific to ASP.NET.
By utilizing async/await in the MVC controller, it is possible to increase thread pool utilization and achieve much better throughput, as explained in the below article,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
In web applications that see a large number of concurrent requests at
start-up or have a bursty load (where concurrency increases suddenly),
making these web service calls asynchronous will increase the
responsiveness of your application. An asynchronous request takes the
same amount of time to process as a synchronous request. For example,
if a request makes a web service call that requires two seconds to
complete, the request takes two seconds whether it is performed
synchronously or asynchronously. However, during an asynchronous call,
a thread is not blocked from responding to other requests while it
waits for the first request to complete. Therefore, asynchronous
requests prevent request queuing and thread pool growth when there are
many concurrent requests that invoke long-running operations.
Async / Await
Actually, Async / Await is a pair of keywords that are just syntactic sugar for creating a callback of an asynchronous task.
Take by example this operation:
public static void DoSomeWork()
{
var task = Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS NOT bubbling up due to the different threads
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// This is the callback
task.ContinueWith((t) => {
// -> Exception is swallowed silently
Console.WriteLine("Completed");
// [RUNS ON WORKER THREAD]
});
}
The code above has several disadvantages. Errors are not passed on and it's hard to read.
But Async and Await come in to help us out:
public async static void DoSomeWork()
{
var result = await Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS bubbling up
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// every thing below is a callback
// (including the calling methods)
Console.WriteLine("Completed");
}
Await calls have to be in Async methods. This has some advantages:
Returns the result of the Task
creates automatically a callback
checks for errors and lets them bubble up in callstack (only up to none-await calls in callstack)
waits for the result
frees up the main thread
runs the callback on the main thread
uses a worker thread from the threadpool for the task
makes the code easy to read
and a lot more
NOTE: Async and Await are used with asynchronous calls not to make these. You have to use Task Libary for this, like Task.Run() .
Here is a comparison between await and none await solutions
This is the none async solution:
public static long DoTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
var task = Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// goes directly further
// WITHOUT waiting until the task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 50 milliseconds
return stopWatch.ElapsedMilliseconds;
}
This is the async method:
public async static Task<long> DoAwaitTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
await Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// Waits until task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 2050 milliseconds
return stopWatch.ElapsedMilliseconds;
}
You can actually call an async method without the await keyword but this means that any Exception here is swallowed in release mode:
public static Stopwatch stopWatch { get; } = new Stopwatch();
static void Main(string[] args)
{
Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
// 2050 (2000 more because of the await)
Console.WriteLine("DoTask: " + DoTask() + " ms");
// 50
Console.ReadKey();
}
Async and Await are not meant for parallel computing. They are used to not block your main thread. When it's about asp.net or Windows applications, blocking your main thread due to a network call is a bad thing. If you do this, your app will get unresponsive or even crash.
Check out MS docs for more examples.
To be honest I still think the best explanation is the one about future and promises on the Wikipedia: http://en.wikipedia.org/wiki/Futures_and_promises
The basic idea is that you have a separate pool of threads that execute tasks asynchronously. When using it. The object does however make the promise that it will execute the operation at some time and give you the result when you request it. This means that it will block when you request the result and hasn't finished, but execute in the thread pool otherwise.
From there you can optimize things: some operations can be implemented async and you can optimize things like file IO and network communication by batching together subsequent requests and/or reordering them. I'm not sure if this is already in the task framework of Microsoft - but if it isn't that would be one of the first things I would add.
You can actually implement the future pattern sort-of with yields in C# 4.0. If you want to know how it works exactly, I can recommend this link that does a decent job: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . However, if you start toying with it yourself, you will notice that you really need language support if you want to do all the cool things -- which is exactly what Microsoft did.
See this fiddle https://dotnetfiddle.net/VhZdLU (and improve it if possible) for running a simple console application which shows usages of Task, Task.WaitAll(), async and await operators in the same program.
This fiddle should clear your execution cycle concept.
Here is the sample code
using System;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met
Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
Console.WriteLine("Now Waiting for Task to be Finished");
Task.WaitAll(a); //Now Waiting
Console.WriteLine("Exiting CommandLine");
}
public static async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperation();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine("Result of LongRunningOperation() is " + result);
}
public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
Console.WriteLine("LongRunningOperation() Started");
await Task.Delay(2000); // 2 second delay
Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
return 1;
}
}
Trace coming from Output Window:
I'd like to give my two cents to this, I'm sorry if any other answer contains what I will explain, I read most of it and haven't find it, but I could have missed something.
I saw a lot of missconceptions and a lot of good explanations, just want to explain async in terms of how it differs from parallel programming, that I believe will make things easier to understand.
When you need to do long computations, processor intensive work, you should opt to use parallel programming, if it's possible, to optimize cores usage. This opens some threads and process things simultaneosly.
Say you have an array of numbers and want to make some expensive long calculation with every and each one of than. Parallel is your friend.
Asyncronous programming is used in a different use case.
It's used to free your thread when you are waiting for something that do not depend on your processor, like IO for example (writing and reading to/from disk), your thread does nothing when you do IO, same thing when you are awaiting for some result from an expensive query to return from DB.
Async methods free your thread when it's waiting for something long to return results. This thread can be used by other parts of your application (in a web app it process other requests, for example) or can return to OS for other use.
When your result is done, the same thread (or another one) is given back to your application to resume processing.
Async programming is not mandatory (but a good practice) in a multithreaded environment like .net, in a web app other threads will respond to new requests, but if you are in a singlethreaded framework like nodejs it's mandatory, because you can't block your only thread, or you won't be able to anwser any other request.
To summarize, long processor intensive calculations will benefit more from parallel programming and long waiting periods that do not depend on your processor, like IO or DB query or a call to some API will benefit more from async programming.
That's why Entity Framework, for example, has an async api to save, list, find, etc...
Remember that async/await is not the same as wait or waitAll, the contexts are different. Async/await release the thread and are asyncronous programming. wait / waitAll blocks all threads (they are not released) to force syncronization in parallel context... different stuff...
Hope this is usefull for someone...
On a higher level:
1) Async keyword enables the await and that's all it does. Async keyword does not run the method in a separate thread. The beginning f async method runs synchronously until it hits await on a time-consuming task.
2) You can await on a method that returns Task or Task of type T. You cannot await on async void method.
3) The moment main thread encounters await on time-consuming task or when the actual work is started, the main thread returns to the caller of the current method.
4) If the main thread sees await on a task that is still executing, it doesn't wait for it and returns to the caller of the current method. In this way, the application remains responsive.
5) Await on processing task, will now execute on a separate thread from the thread pool.
6) When this await task is completed, all the code below it will be executed by the separate thread
Below is the sample code. Execute it and check the thread id
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAwaitDemo
{
class Program
{
public static async void AsynchronousOperation()
{
Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//Task<int> _task = AsyncMethod();
int count = await AsyncMethod();
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//int count = await _task;
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
DependentMethod(count);
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
}
public static async Task<int> AsyncMethod()
{
Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
int count = 0;
await Task.Run(() =>
{
Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
count = 10;
});
Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
return count;
}
public static void DependentMethod(int count)
{
Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
}
static void Main(string[] args)
{
Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
AsynchronousOperation();
Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
}
}
The way I understand it is also, there should be a third term added to the mix: Task.
Async is just a qualifier you put on your method to say it's an asynchronous method.
Task is the return of the async function. It executes asynchronously.
You await a Task. When code execution reaches this line, control jumps out back to caller of your surrounding original function.
If instead, you assign the return of an async function (ie Task) to a variable, when code execution reaches this line, it just continues past that line in the surrounding function while the Task executes asynchronously.
public static void Main(string[] args)
{
string result = DownloadContentAsync().Result;
Console.ReadKey();
}
// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread.
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
using (HttpClient client = new HttpClient())
{
// When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
// If it is already finished, the method continues to run synchronously.
// If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.
// Http request example.
// (In this example I can set the milliseconds after "sleep=")
String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");
Console.WriteLine(result);
// After completing the result response, the state machine will continue to synchronously execute the other processes.
return result;
}
}
The best example is here,enjoy:
is using them equal to spawning background threads to perform long
duration logic?
This article MDSN:Asynchronous Programming with async and await (C#) explains it explicitly:
The async and await keywords don't cause additional threads to be
created. Async methods don't require multithreading because an async
method doesn't run on its own thread. The method runs on the current
synchronization context and uses time on the thread only when the
method is active.
Below is code which reads excel file by opening dialog and then uses async and wait to run asynchronous the code which reads one by one line from excel and binds to grid
namespace EmailBillingRates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
lblProcessing.Text = "";
}
private async void btnReadExcel_Click(object sender, EventArgs e)
{
string filename = OpenFileDialog();
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(filename);
Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
try
{
Task<int> longRunningTask = BindGrid(xlRange);
int result = await longRunningTask;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
//cleanup
// GC.Collect();
//GC.WaitForPendingFinalizers();
//rule of thumb for releasing com objects:
// never use two dots, all COM objects must be referenced and released individually
// ex: [somthing].[something].[something] is bad
//release com objects to fully kill excel process from running in the background
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlWorksheet);
//close and release
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook);
//quit and release
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
}
}
private void btnSendEmail_Click(object sender, EventArgs e)
{
}
private string OpenFileDialog()
{
string filename = "";
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "Excel File Dialog";
fdlg.InitialDirectory = #"c:\";
fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
fdlg.FilterIndex = 2;
fdlg.RestoreDirectory = true;
if (fdlg.ShowDialog() == DialogResult.OK)
{
filename = fdlg.FileName;
}
return filename;
}
private async Task<int> BindGrid(Microsoft.Office.Interop.Excel.Range xlRange)
{
lblProcessing.Text = "Processing File.. Please wait";
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
// dt.Column = colCount;
dataGridView1.ColumnCount = colCount;
dataGridView1.RowCount = rowCount;
for (int i = 1; i <= rowCount; i++)
{
for (int j = 1; j <= colCount; j++)
{
//write the value to the Grid
if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null)
{
await Task.Delay(1);
dataGridView1.Rows[i - 1].Cells[j - 1].Value = xlRange.Cells[i, j].Value2.ToString();
}
}
}
lblProcessing.Text = "";
return 0;
}
}
internal class async
{
}
}
Answering your second question - WHEN to use async - here's a fairly easy approach we use:
Long-running I/O bound task that runs longer than 50ms - use async.
Long-running CPU-bound task - use parallel execution, threads etc.
Explanation: when you're doing I/O work - sending a network request, reading data from disk etc - the actual work is done by "external" silicon (network card, disk controller etc). Once the work is done - the I/O device driver will "ping" the OS back, and the OS will execute your continuation code, callback/etc. Until then the CPU is free to do it's own work (and as a bonus you might also free up a threadpool thread which is a very nice bonus for web app scalability)
P.S. The 50ms threshold is MS's recommendation. Otherwise the overhead added by async (creating the state machine, execution context etc) eats up all the benefits. Can't find the original MS article now, but it's mentioned here too https://www.red-gate.com/simple-talk/dotnet/net-framework/the-overhead-of-asyncawait-in-net-4-5/
The answers here are useful as a general guidance about await/async. They also contain some detail about how await/async is wired. I would like to share some practical experience with you that you should know before using this design pattern.
The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing. On the foreground thread, this is a disaster. The foreground thread carries the burden of constructing your app, including views, view models, initial animations, and whatever else you have boot-strapped with those elements. So when you await the foreground thread, you stop the app. The user waits and waits when nothing appears to happen. This provides a negative user experience.
You can certainly await a background thread using a variety of means:
Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });
// Notice that we do not await the following call,
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}
The complete code for these remarks is at https://github.com/marcusts/xamarin-forms-annoyances. See the solution called AwaitAsyncAntipattern.sln.
The GitHub site also provides links to a more detailed discussion on this topic.
The async is used with a function to makes it into an asynchronous function. The await keyword is used to invoke an asynchronous function synchronously. The await keyword holds the JS engine execution until promise is resolved.
We should use async & await only when we want the result immediately. Maybe the result returned from the function is getting used in the next line.
Follow this blog, It is very well written in simple word
Maybe my insight is relevant. async tells the compiler to treat a function specially, the function is suspendable/resumable, it saves state in some way. await suspends a function, but is also a way to enforce discipline, is restrictive; you need to specify what you are waiting for, you can't just suspend without cause, which is what makes the code more readable and perhaps also more efficient. This opens up another question. Why not await multiple things, why just one at a time? I believe this is because such a pattern established itself and programmers are following the principle of least astonishment. There exists the possibility of ambiguity: are you satisfied with just one of conditions being fulfilled, or do you want all to be fulfilled, perhaps just some of them?

How do I handle Threads in Xamarin apps? [duplicate]

From my understanding one of the main things that async and await do is to make code easy to write and read - but is using them equal to spawning background threads to perform long duration logic?
I'm currently trying out the most basic example. I've added some comments inline. Can you clarify it for me?
// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
Task<int> access = DoSomethingAsync();
// task independent stuff here
// this line is reached after the 5 seconds sleep from
// DoSomethingAsync() method. Shouldn't it be reached immediately?
int a = 1;
// from my understanding the waiting should be done here.
int x = await access;
}
async Task<int> DoSomethingAsync()
{
// is this executed on a background thread?
System.Threading.Thread.Sleep(5000);
return 1;
}
When using async and await the compiler generates a state machine in the background.
Here's an example on which I hope I can explain some of the high-level details that are going on:
public async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperationAsync();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation
{
await Task.Delay(1000); // 1 second delay
return 1;
}
OK, so what happens here:
Task<int> longRunningTask = LongRunningOperationAsync(); starts executing LongRunningOperation
Independent work is done on let's assume the Main Thread (Thread ID = 1) then await longRunningTask is reached.
Now, if the longRunningTask hasn't finished and it is still running, MyMethodAsync() will return to its calling method, thus the main thread doesn't get blocked. When the longRunningTask is done then a thread from the ThreadPool (can be any thread) will return to MyMethodAsync() in its previous context and continue execution (in this case printing the result to the console).
A second case would be that the longRunningTask has already finished its execution and the result is available. When reaching the await longRunningTask we already have the result so the code will continue executing on the very same thread. (in this case printing result to console). Of course this is not the case for the above example, where there's a Task.Delay(1000) involved.
From my understanding one of the main things that async and await do is to make code easy to write and read.
They're to make asynchronous code easy to write and read, yes.
Is it the same thing as spawning background threads to perform long duration logic?
Not at all.
// I don't understand why this method must be marked as 'async'.
The async keyword enables the await keyword. So any method using await must be marked async.
// This line is reached after the 5 seconds sleep from DoSomethingAsync() method. Shouldn't it be reached immediately?
No, because async methods are not run on another thread by default.
// Is this executed on a background thread?
No.
You may find my async/await intro helpful. The official MSDN docs are also unusually good (particularly the TAP section), and the async team put out an excellent FAQ.
Explanation
Here is a quick example of async/await at a high level. There are a lot more details to consider beyond this.
Note: Task.Delay(1000) simulates doing work for 1 second. I think it's best to think of this as waiting for a response from an external resource. Since our code is waiting for a response, the system can set the running task off to the side and come back to it once it's finished. Meanwhile, it can do some other work on that thread.
In the example below, the first block is doing exactly that. It starts all the tasks immediately (the Task.Delay lines) and sets them off to the side. The code will pause on the await a line until the 1 second delay is done before going to the next line. Since b, c, d, and e all started executing at almost the exact same time as a (due to lack of the await), they should finish at roughly the same time in this case.
In the example below, the second block is starting a task and waiting for it to finish (that is what await does) before starting the subsequent tasks. Each iteration of this takes 1 second. The await is pausing the program and waiting for the result before continuing. This is the main difference between the first and second blocks.
Example
Console.WriteLine(DateTime.Now);
// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
var a = Task.Delay(1000);
var b = Task.Delay(1000);
var c = Task.Delay(1000);
var d = Task.Delay(1000);
var e = Task.Delay(1000);
await a;
await b;
await c;
await d;
await e;
}
Console.WriteLine(DateTime.Now);
// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);
OUTPUT:
5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)
Extra info regarding SynchronizationContext
Note: This is where things get a little foggy for me, so if I'm wrong on anything, please correct me and I will update the answer. It's important to have a basic understanding of how this works but you can get by without being an expert on it as long as you never use ConfigureAwait(false), although you will likely lose out on some opportunity for optimization, I assume.
There is one aspect of this which makes the async/await concept somewhat trickier to grasp. That's the fact that in this example, this is all happening on the same thread (or at least what appears to be the same thread in regards to its SynchronizationContext). By default, await will restore the synchronization context of the original thread that it was running on. For example, in ASP.NET you have an HttpContext which is tied to a thread when a request comes in. This context contains things specific to the original Http request such as the original Request object which has things like language, IP address, headers, etc. If you switch threads halfway through processing something, you could potentially end up trying to pull information out of this object on a different HttpContext which could be disastrous. If you know you won't be using the context for anything, you can choose to "not care" about it. This basically allows your code to run on a separate thread without bringing the context around with it.
How do you achieve this? By default, the await a; code actually is making an assumption that you DO want to capture and restore the context:
await a; //Same as the line below
await a.ConfigureAwait(true);
If you want to allow the main code to continue on a new thread without the original context, you simply use false instead of true so it knows it doesn't need to restore the context.
await a.ConfigureAwait(false);
After the program is done being paused, it will continue potentially on an entirely different thread with a different context. This is where the performance improvement would come from -- it could continue on on any available thread without having to restore the original context it started with.
Is this stuff confusing? Hell yeah! Can you figure it out? Probably! Once you have a grasp of the concepts, then move on to Stephen Cleary's explanations which tend to be geared more toward someone with a technical understanding of async/await already.
Further to the other answers, have a look at await (C# Reference)
and more specifically at the example included, it explains your situation a bit
The following Windows Forms example illustrates the use of await in an
async method, WaitAsynchronouslyAsync. Contrast the behavior of that
method with the behavior of WaitSynchronously. Without an await
operator applied to a task, WaitSynchronously runs synchronously
despite the use of the async modifier in its definition and a call to
Thread.Sleep in its body.
private async void button1_Click(object sender, EventArgs e)
{
// Call the method that runs asynchronously.
string result = await WaitAsynchronouslyAsync();
// Call the method that runs synchronously.
//string result = await WaitSynchronously ();
// Display the result.
textBox1.Text += result;
}
// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
await Task.Delay(10000);
return "Finished";
}
// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
// Add a using directive for System.Threading.
Thread.Sleep(10000);
return "Finished";
}
For fastest learning..
Understand method execution flow(with a diagram): 3 mins
Question introspection (learning sake): 1 min
Quickly get through syntax sugar: 5 mins
Share the confusion of a developer : 5 mins
Problem: Quickly change a real-world implementation of normal code to
Async code: 2 mins
Where to Next?
Understand method execution flow(with a diagram): 3 mins
In this image, just focus on #6 (nothing more)
At #6 step, execution ran out of work and stopped. To continue it needs a result from getStringTask(kind of a function). Therefore, it uses an await operator to suspend its progress and give control back(yield) to the caller(of this method we are in). The actual call to getStringTask was made earlier in #2. At #2 a promise was made to return a string result. But when will it return the result? Should we(#1:AccessTheWebAsync) make a 2nd call again? Who gets the result, #2(calling statement) or #6(awaiting statement)?
The external caller of AccessTheWebAsync() also is waiting now. So caller waiting for AccessTheWebAsync, and AccessTheWebAsync is waiting for GetStringAsync at the moment. Interesting thing is AccessTheWebAsync did some work(#4) before waiting perhaps to save time from waiting. The same freedom to multitask is also available for the external caller(and all callers in the chain) and this is the biggest plus of this 'async' thingy! You feel like it is synchronous..or normal but it is not.
#2 and #6 is split so we have the advantage of #4(work while waiting). But we can also do it without splitting. So #2 will be: string urlContents = await client.GetStringAsync("...");. Here we see no advantage but somewhere in the chain one function will be splitting while rest of them call it without splitting. It depends which function/class in the chain you use. This change in behavior from function to function is the most confusing part about this topic.
Remember, the method was already returned(#2), it cannot return again(no second time). So how will the caller know? It is all about Tasks! Task was returned. Task status was waited for (not method, not value). Value will be set in Task. Task status will be set to complete. Caller just monitors Task(#6). So 6# is the answer to where/who gets the result. Further reads for later here.
Question introspection for learning sake: 1 min
Let us adjust the question a bit:
How and When to use async and await Tasks?
Because learning Task automatically covers the other two(and answers your question).
The whole idea is pretty simple. A method can return any data type(double, int, object, etc.) but here we just deny that and force a 'Task' object return! But we still need the returned data(except void), right? That will be set in a standard property inside 'Task' object eg: 'Result' property.
Quickly get through syntax sugar: 5 mins
Original non-async method
internal static int Method(int arg0, int arg1)
{
int result = arg0 + arg1;
IO(); // Do some long running IO.
return result;
}
a brand new Task-ified method to call the above method
internal static Task<int> MethodTask(int arg0, int arg1)
{
Task<int> task = new Task<int>(() => Method(arg0, arg1));
task.Start(); // Hot task (started task) should always be returned.
return task;
}
Did we mention await or async? No. Call the above method and you get a task which you can monitor. You already know what the task returns(or contains).. an integer.
Calling a Task is slightly tricky and that is when the keywords starts to appear. If there was a method calling the original method(non-async) then we need to edit it as given below. Let us call MethodTask()
internal static async Task<int> MethodAsync(int arg0, int arg1)
{
int result = await HelperMethods.MethodTask(arg0, arg1);
return result;
}
Same code above added as image below:
We are 'awaiting' task to be finished. Hence the await(mandatory syntax)
Since we use await, we must use async(mandatory syntax)
MethodAsync with Async as the prefix (coding standard)
await is easy to understand but the remaining two (async,Async) may not be :). Well, it should make a lot more sense to the compiler though.Further reads for later here
So there are 2 parts.
Create 'Task' (only one task and it will be an additional method)
Create syntactic sugar to call the task with await+async(this involves changing existing code if you are converting a non-async method)
Remember, we had an external caller to AccessTheWebAsync() and that caller is not spared either... i.e it needs the same await+async too. And the chain continues(hence this is a breaking change which could affect many classes). It can also be considered a non-breaking change because the original method is still there to be called. Change it's access (or delete and move it inside a task) if you want to impose a breaking change and then the classes will be forced to use Task-method. Anyways, in an async call there will always be a Task at one end and only one.
All okay, but one developer was surprised to see Task
missing...
Share the confusion of a developer: 5 mins
A developer has made a mistake of not implementing Task but it still works! Try to understand the question and just the accepted answer provided here. Hope you have read and fully understood. The summary is that we may not see/implement 'Task' but it is implemented somewhere in a parent/associated class. Likewise in our example calling an already built MethodAsync() is way easier than implementing that method with a Task (MethodTask()) ourself. Most developers find it difficult to get their head around Tasks while converting a code to Asynchronous one.
Tip: Try to find an existing Async implementation (like MethodAsync or ToListAsync) to outsource the difficulty. So we only need to deal with Async and await (which is easy and pretty similar to normal code)
Problem: Quickly change a real-world implementation of normal code to
Async operation: 2 mins
Code line shown below in Data Layer started to break(many places). Because we updated some of our code from .Net framework 4.2.* to .Net core. We had to fix this in 1 hour all over the application!
var myContract = query.Where(c => c.ContractID == _contractID).First();
easypeasy!
We installed EntityFramework nuget package because it has QueryableExtensions. Or in other words it does the Async implementation(task), so we could survive with simple Async and await in code.
namespace = Microsoft.EntityFrameworkCore
calling code line got changed like this
var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
Method signature changed from
Contract GetContract(int contractnumber)
to
async Task<Contract> GetContractAsync(int contractnumber)
calling method also got affected: GetContract(123456); was called as GetContractAsync(123456).Result;
Wait! what is that Result? Good catch! GetContractAsync only returns a Task not the value we wanted(Contract). Once the result of an operation is available, it is stored and is returned immediately on subsequent calls to the Result property.
We can also do a time-out implementation with a similar 'Wait()'
TimeSpan ts = TimeSpan.FromMilliseconds(150);
if (! t.Wait(ts))
Console.WriteLine("The timeout interval elapsed.");
We changed it everywhere in 30 minutes!
But the architect told us not to use EntityFramework library just for this! oops! drama! Then we made a custom Task implementation(yuk!). Which you know how. Still easy! ..still yuk..
Where to Next?
There is a wonderful quick video we could watch about Converting Synchronous Calls to Asynchronous in ASP.Net Core, perhaps that is likely the direction one would go after reading this. Or have I explained enough? ;)
Showing the above explanations in action in a simple console program:
class Program
{
static void Main(string[] args)
{
TestAsyncAwaitMethods();
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
public async static void TestAsyncAwaitMethods()
{
await LongRunningMethod();
}
public static async Task<int> LongRunningMethod()
{
Console.WriteLine("Starting Long Running method...");
await Task.Delay(5000);
Console.WriteLine("End Long Running method...");
return 1;
}
}
And the output is:
Starting Long Running method...
Press any key to exit...
End Long Running method...
Thus,
Main starts the long running method via TestAsyncAwaitMethods. That immediately returns without halting the current thread and we immediately see 'Press any key to exit' message
All this while, the LongRunningMethod is running in the background. Once its completed, another thread from Threadpool picks up this context and displays the final message
Thus, not thread is blocked.
I think you've picked a bad example with System.Threading.Thread.Sleep
Point of an async Task is to let it execute in background without locking the main thread, such as doing a DownloadFileAsync
System.Threading.Thread.Sleep isn't something that is "being done", it just sleeps, and therefore your next line is reached after 5 seconds ...
Read this article, I think it is a great explanation of async and await concept: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
Async & Await Simple Explanation
Simple Analogy
A person may wait for their morning train. This is all they are doing as this is their primary task that they are currently performing. (synchronous programming (what you normally do!))
Another person may await their morning train whilst they smoke a cigarette and then drink their coffee. (Asynchronous programming)
What is asynchronous programming?
Asynchronous programming is where a programmer will choose to run some of his code on a separate thread from the main thread of execution and then notify the main thread on it's completion.
What does the async keyword actually do?
Prefixing the async keyword to a method name like
async void DoSomething(){ . . .
allows the programmer to use the await keyword when calling asynchronous tasks. That's all it does.
Why is this important?
In a lot of software systems the main thread is reserved for operations specifically relating to the User Interface. If I am running a very complex recursive algorithm that takes 5 seconds to complete on my computer, but I am running this on the Main Thread (UI thread) When the user tries to click on anything on my application, it will appear to be frozen as my main thread has queued and is currently processing far too many operations. As a result the main thread cannot process the mouse click to run the method from the button click.
When do you use Async and Await?
Use the asynchronous keywords ideally when you are doing anything that doesn't involve the user interface.
So lets say you're writing a program that allows the user to sketch on their mobile phone but every 5 seconds it is going to be checking the weather on the internet.
We should be awaiting the call the polling calls every 5 seconds to the network to get the weather as the user of the application needs to keep interacting with the mobile touch screen to draw pretty pictures.
How do you use Async and Await
Following on from the example above, here is some pseudo code of how to write it:
//ASYNCHRONOUS
//this is called using the await keyword every 5 seconds from a polling timer or something.
async Task CheckWeather()
{
var weather = await GetWeather();
//do something with the weather now you have it
}
async Task<WeatherResult> GetWeather()
{
var weatherJson = await CallToNetworkAddressToGetWeather();
return deserializeJson<weatherJson>(weatherJson);
}
//SYNCHRONOUS
//This method is called whenever the screen is pressed
void ScreenPressed()
{
DrawSketchOnScreen();
}
Additional Notes - Update
I forgot to mention in my original notes that in C# you can only await methods that are wrapped in Tasks. for example you may await this method:
// awaiting this will return a string.
// calling this without await (synchronously) will result in a Task<string> object.
async Task<string> FetchHelloWorld() {..
You cannot await methods that are not tasks like this:
async string FetchHelloWorld() {..
Feel free to review the source code for the Task class here.
Here is a quick console program to make it clear to those who follow. The TaskToDo method is your long running method that you want to make async. Making it run async is done by the TestAsync method. The test loops method just runs through the TaskToDo tasks and runs them async. You can see that in the results because they don't complete in the same order from run to run - they are reporting to the console UI thread when they complete. Simplistic, but I think the simplistic examples bring out the core of the pattern better than more involved examples:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TestingAsync
{
class Program
{
static void Main(string[] args)
{
TestLoops();
Console.Read();
}
private static async void TestLoops()
{
for (int i = 0; i < 100; i++)
{
await TestAsync(i);
}
}
private static Task TestAsync(int i)
{
return Task.Run(() => TaskToDo(i));
}
private async static void TaskToDo(int i)
{
await Task.Delay(10);
Console.WriteLine(i);
}
}
}
All the answers here use Task.Delay() or some other built in async function. But here is my example that use none of those async functions:
// Starts counting to a large number and then immediately displays message "I'm counting...".
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
Console.WriteLine("Started asyncTest()");
Task<long> task = asyncTest_count();
Console.WriteLine("Started counting, please wait...");
task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
//Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
Console.WriteLine("Finished counting.");
Console.WriteLine("Press any key to exit program.");
Console.ReadLine();
}
static async Task<long> asyncTest_count()
{
long k = 0;
Console.WriteLine("Started asyncTest_count()");
await Task.Run(() =>
{
long countTo = 100000000;
int prevPercentDone = -1;
for (long i = 0; i <= countTo; i++)
{
int percentDone = (int)(100 * (i / (double)countTo));
if (percentDone != prevPercentDone)
{
prevPercentDone = percentDone;
Console.Write(percentDone.ToString() + "% ");
}
k = i;
}
});
Console.WriteLine("");
Console.WriteLine("Finished asyncTest_count()");
return k;
}
This answer aims to provide some info specific to ASP.NET.
By utilizing async/await in the MVC controller, it is possible to increase thread pool utilization and achieve much better throughput, as explained in the below article,
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
In web applications that see a large number of concurrent requests at
start-up or have a bursty load (where concurrency increases suddenly),
making these web service calls asynchronous will increase the
responsiveness of your application. An asynchronous request takes the
same amount of time to process as a synchronous request. For example,
if a request makes a web service call that requires two seconds to
complete, the request takes two seconds whether it is performed
synchronously or asynchronously. However, during an asynchronous call,
a thread is not blocked from responding to other requests while it
waits for the first request to complete. Therefore, asynchronous
requests prevent request queuing and thread pool growth when there are
many concurrent requests that invoke long-running operations.
Async / Await
Actually, Async / Await is a pair of keywords that are just syntactic sugar for creating a callback of an asynchronous task.
Take by example this operation:
public static void DoSomeWork()
{
var task = Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS NOT bubbling up due to the different threads
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// This is the callback
task.ContinueWith((t) => {
// -> Exception is swallowed silently
Console.WriteLine("Completed");
// [RUNS ON WORKER THREAD]
});
}
The code above has several disadvantages. Errors are not passed on and it's hard to read.
But Async and Await come in to help us out:
public async static void DoSomeWork()
{
var result = await Task.Run(() =>
{
// [RUNS ON WORKER THREAD]
// IS bubbling up
throw new Exception();
Thread.Sleep(2000);
return "Hello";
});
// every thing below is a callback
// (including the calling methods)
Console.WriteLine("Completed");
}
Await calls have to be in Async methods. This has some advantages:
Returns the result of the Task
creates automatically a callback
checks for errors and lets them bubble up in callstack (only up to none-await calls in callstack)
waits for the result
frees up the main thread
runs the callback on the main thread
uses a worker thread from the threadpool for the task
makes the code easy to read
and a lot more
NOTE: Async and Await are used with asynchronous calls not to make these. You have to use Task Libary for this, like Task.Run() .
Here is a comparison between await and none await solutions
This is the none async solution:
public static long DoTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
var task = Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// goes directly further
// WITHOUT waiting until the task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 50 milliseconds
return stopWatch.ElapsedMilliseconds;
}
This is the async method:
public async static Task<long> DoAwaitTask()
{
stopWatch.Reset();
stopWatch.Start();
// [RUNS ON MAIN THREAD]
await Task.Run(() => {
Thread.Sleep(2000);
// [RUNS ON WORKER THREAD]
});
// Waits until task is finished
// [RUNS ON MAIN THREAD]
stopWatch.Stop();
// 2050 milliseconds
return stopWatch.ElapsedMilliseconds;
}
You can actually call an async method without the await keyword but this means that any Exception here is swallowed in release mode:
public static Stopwatch stopWatch { get; } = new Stopwatch();
static void Main(string[] args)
{
Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
// 2050 (2000 more because of the await)
Console.WriteLine("DoTask: " + DoTask() + " ms");
// 50
Console.ReadKey();
}
Async and Await are not meant for parallel computing. They are used to not block your main thread. When it's about asp.net or Windows applications, blocking your main thread due to a network call is a bad thing. If you do this, your app will get unresponsive or even crash.
Check out MS docs for more examples.
To be honest I still think the best explanation is the one about future and promises on the Wikipedia: http://en.wikipedia.org/wiki/Futures_and_promises
The basic idea is that you have a separate pool of threads that execute tasks asynchronously. When using it. The object does however make the promise that it will execute the operation at some time and give you the result when you request it. This means that it will block when you request the result and hasn't finished, but execute in the thread pool otherwise.
From there you can optimize things: some operations can be implemented async and you can optimize things like file IO and network communication by batching together subsequent requests and/or reordering them. I'm not sure if this is already in the task framework of Microsoft - but if it isn't that would be one of the first things I would add.
You can actually implement the future pattern sort-of with yields in C# 4.0. If you want to know how it works exactly, I can recommend this link that does a decent job: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . However, if you start toying with it yourself, you will notice that you really need language support if you want to do all the cool things -- which is exactly what Microsoft did.
See this fiddle https://dotnetfiddle.net/VhZdLU (and improve it if possible) for running a simple console application which shows usages of Task, Task.WaitAll(), async and await operators in the same program.
This fiddle should clear your execution cycle concept.
Here is the sample code
using System;
using System.Threading.Tasks;
public class Program
{
public static void Main()
{
var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met
Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
Console.WriteLine("Now Waiting for Task to be Finished");
Task.WaitAll(a); //Now Waiting
Console.WriteLine("Exiting CommandLine");
}
public static async Task MyMethodAsync()
{
Task<int> longRunningTask = LongRunningOperation();
// independent work which doesn't need the result of LongRunningOperationAsync can be done here
Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine("Result of LongRunningOperation() is " + result);
}
public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation
{
Console.WriteLine("LongRunningOperation() Started");
await Task.Delay(2000); // 2 second delay
Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
return 1;
}
}
Trace coming from Output Window:
I'd like to give my two cents to this, I'm sorry if any other answer contains what I will explain, I read most of it and haven't find it, but I could have missed something.
I saw a lot of missconceptions and a lot of good explanations, just want to explain async in terms of how it differs from parallel programming, that I believe will make things easier to understand.
When you need to do long computations, processor intensive work, you should opt to use parallel programming, if it's possible, to optimize cores usage. This opens some threads and process things simultaneosly.
Say you have an array of numbers and want to make some expensive long calculation with every and each one of than. Parallel is your friend.
Asyncronous programming is used in a different use case.
It's used to free your thread when you are waiting for something that do not depend on your processor, like IO for example (writing and reading to/from disk), your thread does nothing when you do IO, same thing when you are awaiting for some result from an expensive query to return from DB.
Async methods free your thread when it's waiting for something long to return results. This thread can be used by other parts of your application (in a web app it process other requests, for example) or can return to OS for other use.
When your result is done, the same thread (or another one) is given back to your application to resume processing.
Async programming is not mandatory (but a good practice) in a multithreaded environment like .net, in a web app other threads will respond to new requests, but if you are in a singlethreaded framework like nodejs it's mandatory, because you can't block your only thread, or you won't be able to anwser any other request.
To summarize, long processor intensive calculations will benefit more from parallel programming and long waiting periods that do not depend on your processor, like IO or DB query or a call to some API will benefit more from async programming.
That's why Entity Framework, for example, has an async api to save, list, find, etc...
Remember that async/await is not the same as wait or waitAll, the contexts are different. Async/await release the thread and are asyncronous programming. wait / waitAll blocks all threads (they are not released) to force syncronization in parallel context... different stuff...
Hope this is usefull for someone...
On a higher level:
1) Async keyword enables the await and that's all it does. Async keyword does not run the method in a separate thread. The beginning f async method runs synchronously until it hits await on a time-consuming task.
2) You can await on a method that returns Task or Task of type T. You cannot await on async void method.
3) The moment main thread encounters await on time-consuming task or when the actual work is started, the main thread returns to the caller of the current method.
4) If the main thread sees await on a task that is still executing, it doesn't wait for it and returns to the caller of the current method. In this way, the application remains responsive.
5) Await on processing task, will now execute on a separate thread from the thread pool.
6) When this await task is completed, all the code below it will be executed by the separate thread
Below is the sample code. Execute it and check the thread id
using System;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncAwaitDemo
{
class Program
{
public static async void AsynchronousOperation()
{
Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//Task<int> _task = AsyncMethod();
int count = await AsyncMethod();
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
//int count = await _task;
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
DependentMethod(count);
Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
}
public static async Task<int> AsyncMethod()
{
Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
int count = 0;
await Task.Run(() =>
{
Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(20000);
count = 10;
});
Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
return count;
}
public static void DependentMethod(int count)
{
Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
}
static void Main(string[] args)
{
Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
AsynchronousOperation();
Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
}
}
The way I understand it is also, there should be a third term added to the mix: Task.
Async is just a qualifier you put on your method to say it's an asynchronous method.
Task is the return of the async function. It executes asynchronously.
You await a Task. When code execution reaches this line, control jumps out back to caller of your surrounding original function.
If instead, you assign the return of an async function (ie Task) to a variable, when code execution reaches this line, it just continues past that line in the surrounding function while the Task executes asynchronously.
public static void Main(string[] args)
{
string result = DownloadContentAsync().Result;
Console.ReadKey();
}
// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread.
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
using (HttpClient client = new HttpClient())
{
// When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
// If it is already finished, the method continues to run synchronously.
// If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.
// Http request example.
// (In this example I can set the milliseconds after "sleep=")
String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");
Console.WriteLine(result);
// After completing the result response, the state machine will continue to synchronously execute the other processes.
return result;
}
}
The best example is here,enjoy:
is using them equal to spawning background threads to perform long
duration logic?
This article MDSN:Asynchronous Programming with async and await (C#) explains it explicitly:
The async and await keywords don't cause additional threads to be
created. Async methods don't require multithreading because an async
method doesn't run on its own thread. The method runs on the current
synchronization context and uses time on the thread only when the
method is active.
Below is code which reads excel file by opening dialog and then uses async and wait to run asynchronous the code which reads one by one line from excel and binds to grid
namespace EmailBillingRates
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
lblProcessing.Text = "";
}
private async void btnReadExcel_Click(object sender, EventArgs e)
{
string filename = OpenFileDialog();
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(filename);
Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
try
{
Task<int> longRunningTask = BindGrid(xlRange);
int result = await longRunningTask;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
//cleanup
// GC.Collect();
//GC.WaitForPendingFinalizers();
//rule of thumb for releasing com objects:
// never use two dots, all COM objects must be referenced and released individually
// ex: [somthing].[something].[something] is bad
//release com objects to fully kill excel process from running in the background
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlWorksheet);
//close and release
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook);
//quit and release
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
}
}
private void btnSendEmail_Click(object sender, EventArgs e)
{
}
private string OpenFileDialog()
{
string filename = "";
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "Excel File Dialog";
fdlg.InitialDirectory = #"c:\";
fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
fdlg.FilterIndex = 2;
fdlg.RestoreDirectory = true;
if (fdlg.ShowDialog() == DialogResult.OK)
{
filename = fdlg.FileName;
}
return filename;
}
private async Task<int> BindGrid(Microsoft.Office.Interop.Excel.Range xlRange)
{
lblProcessing.Text = "Processing File.. Please wait";
int rowCount = xlRange.Rows.Count;
int colCount = xlRange.Columns.Count;
// dt.Column = colCount;
dataGridView1.ColumnCount = colCount;
dataGridView1.RowCount = rowCount;
for (int i = 1; i <= rowCount; i++)
{
for (int j = 1; j <= colCount; j++)
{
//write the value to the Grid
if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null)
{
await Task.Delay(1);
dataGridView1.Rows[i - 1].Cells[j - 1].Value = xlRange.Cells[i, j].Value2.ToString();
}
}
}
lblProcessing.Text = "";
return 0;
}
}
internal class async
{
}
}
Answering your second question - WHEN to use async - here's a fairly easy approach we use:
Long-running I/O bound task that runs longer than 50ms - use async.
Long-running CPU-bound task - use parallel execution, threads etc.
Explanation: when you're doing I/O work - sending a network request, reading data from disk etc - the actual work is done by "external" silicon (network card, disk controller etc). Once the work is done - the I/O device driver will "ping" the OS back, and the OS will execute your continuation code, callback/etc. Until then the CPU is free to do it's own work (and as a bonus you might also free up a threadpool thread which is a very nice bonus for web app scalability)
P.S. The 50ms threshold is MS's recommendation. Otherwise the overhead added by async (creating the state machine, execution context etc) eats up all the benefits. Can't find the original MS article now, but it's mentioned here too https://www.red-gate.com/simple-talk/dotnet/net-framework/the-overhead-of-asyncawait-in-net-4-5/
The answers here are useful as a general guidance about await/async. They also contain some detail about how await/async is wired. I would like to share some practical experience with you that you should know before using this design pattern.
The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing. On the foreground thread, this is a disaster. The foreground thread carries the burden of constructing your app, including views, view models, initial animations, and whatever else you have boot-strapped with those elements. So when you await the foreground thread, you stop the app. The user waits and waits when nothing appears to happen. This provides a negative user experience.
You can certainly await a background thread using a variety of means:
Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });
// Notice that we do not await the following call,
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}
The complete code for these remarks is at https://github.com/marcusts/xamarin-forms-annoyances. See the solution called AwaitAsyncAntipattern.sln.
The GitHub site also provides links to a more detailed discussion on this topic.
The async is used with a function to makes it into an asynchronous function. The await keyword is used to invoke an asynchronous function synchronously. The await keyword holds the JS engine execution until promise is resolved.
We should use async & await only when we want the result immediately. Maybe the result returned from the function is getting used in the next line.
Follow this blog, It is very well written in simple word
Maybe my insight is relevant. async tells the compiler to treat a function specially, the function is suspendable/resumable, it saves state in some way. await suspends a function, but is also a way to enforce discipline, is restrictive; you need to specify what you are waiting for, you can't just suspend without cause, which is what makes the code more readable and perhaps also more efficient. This opens up another question. Why not await multiple things, why just one at a time? I believe this is because such a pattern established itself and programmers are following the principle of least astonishment. There exists the possibility of ambiguity: are you satisfied with just one of conditions being fulfilled, or do you want all to be fulfilled, perhaps just some of them?

Custom message pumping with c# async calls

I'm creating my own UI handling logic that runs on a single thread. Basically, what I'm doing is
void HandlerMain()
{
while (true)
{
Task[] events = PumpEvents();
Task.WaitAll(events);
}
}
where one example task that PumpEvents() returns is
async Task ButtonClick()
{
var httpClient = new HttpClient();
string s = await httpClient.GetStringAsync("http://microsoft.com");
Console.WriteLine(s);
}
The problem of my code is, if one of events takes a long time, it's stuck at Task.WaitAll(), so it can't pump new events making the UI not responsive. Is there any other method than WaitAll() something like
Task[] remainingEvents = PumpEvents();
while (true)
{
remainingEvents = WaitUntilEveryTasksAwait(remainingEvents);
remainingEvents.Append(PumpEvents());
}
Maybe I'm on wrong track. I'd appreciate your advice!
#ScottChamberlain No. The built-in UI processor, say WPF, correctly handles async events so whenever the async events do "await", it skips the current context and handles the next events. I want to duplicate this behavior
Based on your comment to me I now understand what your problem is. You need more logic than your simple while(true) loop to be able to process the await messages. The entire system is built up upon the class SynchronizationContext, what you will need to do is derive your own class from SynchronizationContext and override it's methods to queue up your work to be done inside your while loop.
See this article from Stephen Cleary to give you more information on how a Synchronization Context works and posibly some ideas on where to start writing your own.
If I'm understanding, you don't actually need to wait until those tasks are complete to continue. Just remove the call to Task.WaitAll.
For the record, Task.WaitAll is synchronous -- it blocks. You're better off using Task.WhenAll, which returns a task that completes when all of the provided tasks are complete. That lets you await it just like you'd await any of the individual tasks. Just doing that would solve the problem and keep the UI responsive.
E.g.:
async Task HandlerMain()
{
while (true)
{
Task[] events = PumpEvents();
await Task.WhenAll(events);
}
}
Of course, in this case, depending on what was calling HandlerMain, you'd still have the problem where PumpEvents was hung up waiting on the long-running task.
This starts to lead down the path of questions like, "Why are you writing your own custom UI message pump when WPF and WinForms have that problem already solved?"

Why does the file async API block

I am writing a simple metro app. However, the API blocks when accessing files. By blocking, I mean the programs waits forever. Creating/opening a file or folder should take at most a few seconds. In this case, it takes forever.
When I run the program, it never comes back from OnTest. Is it what you get.
I understand .Wait will wait for the creation of files and folders to finishe. Maybe that's not great design. However, that's not the point.
My question is:
Do you get the same behavior (blocks the program forever)
Is it what's supposed to happen or is it a bug in WinRT? (I am using the consumer preview)
If that's the expected behavior, why does it take forever?
Here is the XAML code:
<Button Click="OnTest">Test</Button>
Here is the C# code:
private async void OnTest(object sender, RoutedEventArgs e)
{
var t = new Cache("test1");
t = new Cache("test2");
t = new Cache("test3");
}
class Cache
{
public Cache(string name)
{
TestRetrieve(name).Wait();
}
public static async Task TestRetrieve(string name)
{
StorageFolder rootFolder = ApplicationData.Current.LocalFolder;
var _folder = await rootFolder.CreateFolderAsync(name, CreationCollisionOption.OpenIfExists);
var file = await _folder.CreateFileAsync("test.xml", CreationCollisionOption.OpenIfExists);
}
}
It blocks on the second call to new Cache("test2");
I have not attempted to run your program or reproduce your problem, but I can make an educated guess as to what is going on.
Suppose you wrote yourself the following to-do list:
Put a letter to mom in the mailbox.
Set the alarm to wake me up as soon as I've read her reply.
Go to sleep.
Check the mailbox for the reply.
Read the reply.
Now do everything on that list strictly in order from top to bottom. What happens?
The problem is not with the post office or with mom; they are picking up the letter you put in the mailbox, sending it to mom, mom is writing her reply and the post office is bringing it back to you. The problem is that you never get to the fourth step because you only can start the fourth step after you complete the fifth step and the alarm wakes you up. You'll sleep forever because you are essentially waiting for your future self to wake your present self up.
Eric, Thank you for the explanation.
You're welcome.
However, I am still confused as to why my code does not work.
OK, let's break it down. What does your program really do? Let's simplify:
void M()
{
Task tx = GetATask();
tx.Wait();
}
async Task GetATask()
{
Task ty = DoFileSystemThingAsync();
await ty;
DoSomethingElse();
}
First off: what is a task? A task is an object that represents (1) a job to be done, and (2) a delegate to the continuation of the task: the thing that needs to happen after the task is done.
So you call GetATask. What does it do? Well, the first thing it does is it makes a Task and stores it in ty. That task represents the job "start some operation on the disk, and notify the I/O completion thread when it is done".
What is the continuation of that task? What has to happen after that task is done? DoSomethingElse needs to be called. So the compiler transforms the await into a bunch of code that tells the task to ensure that DoSomethingElse is called when the task is done.
The moment that the continuation of the I/O task has been set, the method GetATask returns a task to the caller. What task is that? This is a different task than the task that got stored into ty. The task that is returned is the task that represents the job do everything that the method GetATask needs to do.
What is the continuation of that task? We don't know! That is up to the caller of GetATask to decide.
OK, so let's review. We have two task objects. One represents the task "go do this thing on the file system". It will be done when the file system does its work. It's continuation is "call DoSomething". We have a second task object that represents the job "do everything in the body of GetATask". It will be done after the call to DoSomethingElse returns.
Again: the first task will be complete when the file I/O succeeds. When that happens, the file I/O completion thread will send a message to the main thread saying "hey, that file I/O you were waiting for is done. I am telling you this because it is now time for you to call DoSomethingElse".
But the main thread is not examining its message queue. Why not? Because you told it to synchronously wait until everything in GetATask, including DoSomethingElse, is complete. But the message that is telling you to run DoSomethingElse now cannot be processed because you are waiting for DoSomethingElse to be complete.
Now is it clear? You are telling your thread to wait until your thread is done running DoSomethingElse before you check to see if "please call DoSomethingElse" is in the queue of work to be performed on this thread! You are waiting until you have read the letter from mom, but the fact that you are waiting synchronously means that you are not checking your mailbox to see if the letter has arrived.
Calling Wait is obviously wrong in this case because you are waiting for yourself to do something in the future, and that's not going to work. But more generally, calling Wait completely negates the entire point of being async in the first place. Just don't do that; it doesn't make any sense to say both "I want to be asynchronous" and "but I want to synchronously wait". Those are opposites.
You're using Wait() in the constructor of the Cache class. That's going to block until whatever is currently executing asynchronously has finished.
This is not the way to design this. Constructors and async do not make sense. Perhaps a factory method approach like this would work better:
public class Cache
{
private string cacheName;
private Cache(string cacheName)
{
this.cacheName = cacheName;
}
public static async Cache GetCacheAsync(string cacheName)
{
Cache cache = new Cache(cacheName);
await cache.Initialize();
return cache;
}
private async void Initialize()
{
StorageFolder rootFolder = ApplicationData.Current.LocalFolder;
var _folder = await rootFolder.CreateFolderAsync(this.cacheName, CreationCollisionOption.OpenIfExists);
var file = await _folder.CreateFileAsync("test.xml", CreationCollisionOption.OpenIfExists);
}
}
And then you use it like this:
await Task.WhenAll(Cache.GetCacheAsync("cache1"), Cache.GetCacheAsync("cache2"), Cache.GetCacheAsync("cache3"));
TestRetrieve(name).Wait();
You're telling it to block specifically by using the .Wait() call.
Remove the .Wait() and it shouldn't block anymore.
The existing answers provide very thorough explanations of why it blocks and code examples of how to make it not block, but these many be 'more information' than some users understand. Here is a simpler 'mechanics oriented' explanation..
The way the async/await pattern works, each time you await an async method, you are "attaching" that method's async context to the current method's async context. Imagine await as passing in a magic hidden paramater "context". This context-paramater is what allows nested await calls to attach to the existing async context. (this is just an analogy...the details are more complicated than this)
If you are inside an async method, and you call a method synchronously, that synchronous method doesn't get that magic hidden async context paramater, so it can't attach anything to it. It's then an invalid operation to create a new async context inside that method using 'wait', because the new context does not get attached to your thread's existing top-level async context (because you don't have it!).
Described in terms of the code-example, the TestRetrieve(name).Wait(); is not doing what you think it's doing. It's actually telling the current thread to re-enter the async-activity-wait-loop at the top. In this example, this is the UI-thread, which is called your OnTest handler. The following picture may help:
UI-thread context looks like this...
UI-Thread ->
OnTest
Since you didn't have a connected chain of await/async calls all the way down, you never "attached' the TestRetrieve async context to the above UI-Thread async chain. Effectively, that new context you made is just dangling off in nowhere land. So when you "Wait" the UIThread, it just goes right back to the top.
For async to work, you need to keep a connected async/await chain from the top-level synchronous thread (in this case it's the UI-thread doing this) through all async actions you need to do. You can't make a constructor async, so you can't chain an async context into a constructor. You need to construct the object synchronously and then await TestRetrieve from outside. Remove the 'Wait' line from your constructor and do this...
await (new Cache("test1")).TestRetrieve("test1");
When you do this, the 'TestRetrieve' async context is properly attached, so the chain looks like this:
UI-Thread ->
OnTest ->
TestRetrieve
Now the UI-thread async-loop-handler can properly resume TestRetrieve during async completions and your code will work as expected.
If you want to make an 'async constructor', you need to do something like Drew's GetCacheAsync pattern, where you make a static Async method which constructs the object synchronously and then awaits the async method. This creates the proper async chain by awaiting and 'attaching' the context all the way down.

Categories

Resources