I am new to threading and asynchronous programming. I am trying to learn these concepts and so far i understand it but have a question to ask.
Lets say i want to call a method called GetAllUsers(), which takes long time to execute, in a way it does not block the resources and keeps UI responsive. So, what I understand is that it can be done in 3 ways (please let me know if these are correct or have i totally got it wrong):-
1) Threads: I can spawn a new thread and give GetAllUsers method as a threadstart. This will start the execution of the method on a different thread keeping my ui responsive and when the call is complete i can use the routing technique to update the UI controls i.e. InvokeRequired. Is my understanding correct ?
Or
2) Asynchronous Delegates: I can create a delegate. Create a new instance of it and point it to method GetAllUsers. Then use the BeginInvoke method. The BeginInvoke under the hood will spawn a new thread and run my method keeping the UI responsive. When call is complete, the callback method will be called and again the routing technique will be used to update the controls on GUI thread. Is my understanding correct?
Or
3) Async/Await: Mark the outer method as async and mark the call to method GetAllUsers as await. This will also keep the UI responsive as the thread that is running it can jump out and do some other work until the call to this slow method completes. Is my understanding correct?
Now, the question is - If you read the 2nd para on the link below, it says that async/await does not cause additional threads to be created. So how does the async/await manages to give the same output as the first 2solution above without creating any additional threads. The solution 1 and 2 will result in multi-threads but the async solution will not. How does the async/await works under the hood.?
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx#BKMK_Threads
Invoke : Executes on the UI thread, but calling thread waits for completion before continuing. Control. BeginInvoke : Executes on the UI thread, and calling thread doesn't wait for completion.
Invoke: Executes on the UI thread, but calling thread waits for completion before continuing. Control. BeginInvoke: Executes on the UI thread, and calling thread doesn't wait for completion.
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. You can use Task.
Short answer: yes. According to the docs for UploadStringAsync: The string is sent asynchronously using thread resources that are automatically allocated from the thread pool. And BeginInvoke uses a thread from the thread pool to accomplish its asynchronous behavior.
Is my understanding correct?
Yes, your understanding is correct.
Now, the question is - If you read the 2nd para on the link below, it says that async/await does not cause additional threads to be created. So how does the async/await manages to give the same output as the first 2solution above without creating any additional threads
The async
modifier and await
operator do not necessarily create new threads. The actual mechanisms to perform the asynchrony are handled by the type on which you call await
. If you use await Task.Run(() => YourMethod());
, then Task.Run
does use a thread pool thread to perform the operation.
However, if you can rework your methods so that GetAllUsers
uses asynchronous IO calls and not threads, then await
will not need to use threading to be asynchronous. For example, if GetAllUsers
spends most of its time waiting on a download from a server, using an asynchronous web API will allow you to make that method asynchronous without using extra threads.
In this case, even if you do have to use Task.Run
with await
, there is a nice advantage here - you can rework your method to use await
, and not mess up its logical control flow, keep the exception handling clean, and not have to worry about using BeginInvoke
to push back to the UI thread - with await
, all of that "mess" is handled for you, and your code can stay very close to the original, non-asynchronous code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With