Asynchronous operation and thread in C# - c#

Asynchronous programming is a technique that calls a long running method in the background so that the UI thread remains responsive. It should be used while calling a web service or database query or any I/O bound operation. when the asynchronous method completes, it returns the result to the main thread. In this way, the program's main thread does not have to wait for the result of an I/O bound operation and continues to execute further without blocking/freezing the UI. This is ok.
As far as I know the asynchronous method executes on a background worker thread. The runtime makes availabe the thread either from the threadpool or it may create a brand new thread for its execution.
But I have read in many posts that an asynchronous operation may execute on a separate thread or without using any thread. Now I am very confused.
1) Could you please help clarifying in what situation an asynchronous operation will not use a thread?
2) What is the role of processor core in asynchronous operation?
3) How it is different from multithreading? I know one thing that multithreading is usefult with compute-bound operation.
Please help.

IO (let's say a database-operation over the network) is a good example for all three:
you basically just register a callback the OS will finally call (maybe on a then newly created thread) when the IO-Operation finished. There is no thread sitting around and waiting - the resurrection will be triggered by hardware-events (or at least by a OS process usually outside user-space)
it might have none (see 1)
in Multithreading you use more than one thread (your background-thread) and there one might idle sit there doing nothing (but using up system-resources) - this is of course different if you have something to compute (so the thread is not idle waiting for external results) - there it makes sense to use a background-worker-thread

Asynchronous operations don't actually imply much of anything about how they are processed, only that they would like the option to get back to you later with your results. By way of example:
They may (as you've mentioned) split off a compute-bound task onto an independent thread, but this is not the only use case.
They may sometimes complete synchronously within the call that launches them, in which case no additional thread is used. This may happen with an I/O request if there is already enough buffer content (input) or free buffer space (output) to service the request.
They may simply drop off a long-running I/O request to the system; in this case the callback is likely to occur on a background thread after receiving notification from an I/O completion port.
On completion, a callback may be delivered later on the same thread; this is especially common with events within a UI framework, such as navigation in a WebBrowser.

Asynchronity doesn't say anything about thread. Its about having some kind of callbacks which will be handled inside a "statemachine" (not really correct but you can think of it like events ). Asynchronity does not raise threads nor significantly allocate system ressources. You can run as many asynchronous methods as you want to.
Threads do have a real imply on your system and you have a hughe but limited number you can have at once.
Io operations are mostly related to others controllers (HDD, NIC,...) What now happens if you create a thread is that a thread of your application which has nothing to do waits for the controllers to finish. In async as Carsten and Jeffrey already mentioned you just get some kind of callback mechanism so your thread continues to do other work, methods and so on.
Also keep in mind that each thread costs ressources (RAM, Performance,handles Garbage Collection got worse,...) and may even and up in exceptions (OutOfMemoryException...)
So when to use Threads? Absolutly only if you really need it. If there is a async api use it unless you have really important reasons to not use it.
In past days the async api was really painfull, thats why many people used threads when ever they need just asynchronity.
For example node.js refuses the use of mulptile thread at all!
This is specially important if you handle multiple requests for example in services / websites where there is always work to do. There is also a this short webcast with Jeffrey Richter about this which helped me to understand
Also have a look at this MSDN article
PS: As a side effect sourcecode with async and await tend to be more readable

Related

Is it pointless to use Threads inside Tasks in C#?

I know the differences between a thread and a task., but I cannot understand if creating threads inside tasks is the same as creating only threads.
It depends on how you use the multithreaded capabilities and the asynchronous programming semantics of the language.
Simple facts first. Assume you have an initial, simple, single-threaded, and near empty application (that just reads a line of input with Console.ReadLine for simplicity sake). If you create a new Thread, then you've created it from within another thread, the main thread. Therefore, creating a thread from within a thread is a perfectly valid operation, and the starting point of any multithreaded application.
Now, a Task is not a thread per se, but it gets executed in one when you do Task.Run which is selected from a .NET managed thread pool. As such, if you create a new thread from within a task, you're essentially creating a thread from within a thread (same as above, no harm done). The caveat here is, that you don't have control of the thread or its lifetime, that is, you can't kill it, suspend it, resume it, etc., because you don't have a handle to that thread. If you want some unit of work done, and you don't care which thread does it, just that's it not the current one, then Task.Run is basically the way to go. With that said, you can always start a new thread from within a task, actually, you can even start a task from within a task, and here is some official documentation on unwrapping nested tasks.
Also, you can await inside a task, and create a new thread inside an async method if you want. However, the usability pattern for async and await is that you use them for I/O bound operations, these are operations that require little CPU time but can take long because they need to wait for something, such as network requests, and disk access. For responsive UI implementations, this technique is often used to prevent blocking of the UI by another operation.
As for being pointless or not, it's a use case scenario. I've faced situations where that could have been the solution, but found that redesigning my program logic so that if I need to use a thread from within a task, then what I do is to have two tasks instead of one task plus the inner thread, gave me a cleaner, and more readable code structure, but that it's just personal flair.
As a final note, here are some links to official documentation and another post regarding multithreaded programming in C#:
Async in Depth
Task based asynchronous programming
Chaining Tasks using Continuation Tasks
Start multiple async Tasks and process them as they complete
Should one use Task.Run within another Task
It depends how you use tasks and what your reason is for wanting another thread.
Task.Run
If you use Task.Run, the work will "run on the ThreadPool". It will be done on a different thread than the one you call it from. This is useful in a desktop application where you have a long-running processor-intensive operation that you just need to get off the UI thread.
The difference is that you don't have a handle to the thread, so you can't control that thread in any way (suspend, resume, kill, reuse, etc.). Essentially, you use Task.Run when you don't care which thread the work happens on, as long as it's not the current one.
So if you use Task.Run to start a task, there's nothing stopping you from starting a new thread within, if you know why you're doing it. You could pass the thread handle between tasks if you specifically want to reuse it for a specific purpose.
Async methods
Methods that use async and await are used for operations that use very little processing time, but have I/O operations - operations that require waiting. For example, network requests, read/writing local storage, etc. Using async and await means that the thread is free to do other things while you wait for a response. The benefits depend on the type of application:
Desktop app: The UI thread will be free to respond to user input while you wait for a response. I'm sure you've seen some programs that totally freeze while waiting for a response from something. This is what asynchronous programming helps you avoid.
Web app: The current thread will be freed up to do any other work required. This can include serving other incoming requests. The result is that your application can handle a bigger load than it could if you didn't use async and await.
There is nothing stopping you from starting a thread inside an async method too. You might want to move some processor-intensive work to another thread. But in that case you could use Task.Run too. So it all depends on why you want another thread.
It would be pointless in most cases of everyday programming.
There are situations where you would create threads.

Threads, Task, async/await, Threadpool

I am getting really confused here about multithreading :(
I am reading about the C# Async/Await keywords. I often read, that by using this async feature, the code gets executed "non-blocking". People put code examples in two categories "IO-Bound" and "CPU-bound" - and that I should not use a thread when I execute io-bound things, because that thread will just wait ..
I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ?
If I use the Threadpool, an instance of "Thread"-class, delegate.BeginInvoke or the TPL -- every asynchronous execution is done on another thread. (with or without a callback)
What you are missing is that not every asynchronous operation is done on another thread. Waiting on an IO operation or a web service call does not require the creation of a thread. On Windows this is done by using the OS I/O Completion Ports.
What happens when you call something like Stream.ReadAsync is that the OS will issue a read command to the disk and then return to the caller. Once the disk completes the read the notifies the OS kernel which will then trigger a call back to your processes. So there is no need to create a new threadpool thread that will just sit and block.
What is meant is this:
Suppose you query some data from a database (on another server) - you will send a request and just wait for the answer. Instead of having a thread block and wait for the return it's better to register an callback that get's called when the data comes back - this is (more or less) what async/await does.
It will free the thread to do other things (give it back to the pool) but once your data come back asynchronously it will get another thread and continue your code at the point you left (it's really some kind of state-machine that handles that).
If your calculation is really CPU intensive (let's say you are calculating prime-numbers) things are different - you are not waiting for some external IO, you are doing heavy work on the CPU - here it's a better idea to use a thread so that your UI will not block.
I dont get it... If I do not want a user have to wait for an operation, I have to execute that operation on another thread, right ?
Not exactly. An operation will take however long it is going to take. When you have a single-user application, running long-running things on a separate thread lets the user interface remain responsive. At the very least this allows the UI to have something like a "Cancel" button that can take user input and cancel processing on the other thread. For some single-user applications, it makes sense to allow the user to keep doing other things while a long-running task completes (for example let them work on one file while another file is uploading or downloading).
For web applications, you do not want to block a thread from the thread pool during lengthy(ish) IO, for example while reading from a database or calling another web service. This is because there are only a limited number of threads available in the thread pool, and if they are all in use, the web server will not be able to accept additional HTTP requests.

Last time. Is await working with threads?

I saw some similar questions before, just want to clarify it.
In this article, it is said "There is no thread" for async calls.
However, in another one, it is said
Here, however, we’re running the callback to update the Text of
textBox1on some arbitrary thread, wherever the Task Parallel Library
(TPL) implementation of ContinueWith happened to put it.
Also, in some cases, when i was calling ContinueWith in my project, i also got "cross-thread access exception.
So, who is right?
ANSWER: thanks to i3arnon. After reading first article more carefully, i found this place
So, we see that there was no thread while the request was in flight.
When the request completed, various threads were “borrowed” or had
work briefly queued to them. This work is usually on the order of a
millisecond or so (e.g., the APC running on the thread pool) down to a
microsecond or so (e.g., the ISR). But there is no thread that was
blocked, just waiting for that request to complete.
Both are. When you have code running on your CPU there's always a thread running it. The question is what happens when you don't have code to run, for example when you are waiting for an IO operation to complete.
If you use async await where you should there would be no thread idly waiting for that operation to complete, and only after it has completed a thread will be given (usually by the Thread Pool) to continue running code on your CPU.
When you don't use async-await (or a different asynchronous paradigm like Begin-End) you would hold a thread throughout the operation, even in the IO parts of it, which is a waste of resources.
It's important to add that although most asynchronous examples regard IO operations, that's not always the case. In some cases it's reasonable to treat a CPU bound operation (where you do hold a thread throughout the whole operation) asynchronously.

Does an asynchronous call require an extra thread in the current process or use another thread in a thread pool?

I'm referring to this answer where it says it's not required, there are few specific assumptions though. That question is general.
I'm using C#
Asynchronous process is doing nothing but just calling an external API and waiting for the reply.
Generally yes, but there is at least one exception I can think of. To initiate an asynchronous operation you must transfer the operation outside of the context of the caller. What I mean by that is that the caller should not block waiting for the operation to complete. That usually means that the operation has to move to a newly created thread, a thread from the ThreadPool, an IO completion port, another process, or the like.
I said there was one exception that came to mind. If we slightly pervert our definition of asynchronous we can allow for scenarios in which the initiator does not block waiting for the operation to complete without actually moving the operation to another thread. The best example of this is the UI message pump. In .NET it is easy enough to call Control.BeginInvoke from the UI thread itself to post the execution of a delegate on the same thread. The initiator clearly would not block waiting for the delegate to complete and yet the delegate would eventually start executing on the same thread. This is definitely a perversion of what we typically think of the term asychronous because in this scenario the operation blocks until the caller completes instead of the other way around.
Your question is too general. The Windows API has specific support for asynchronous I/O without using a thread, check the docs for ReadFile() for example. The lpOverlapped argument controls this. The ReadFileEx() function allows specifying an I/O completion callback. This is well covered by the .NET framework classes.
Calling a slow external API function is not covered by this mechanism, you need to spin up your own thread.
Yes, a Pool Thread is used. But that thread is not hanging around waiting for the external device. The thread is re-used and a(nother) thread is called upon when the I/O is completed.
See I/O Asynchronous Completion on MSDN.

What happens if an asynchronous delegate call never returns?

I found a decent looking example of how to call a delegate asynchronously with a timeout... http://www.eggheadcafe.com/tutorials/aspnet/847c94bf-4b8d-4a66-9ae5-5b61f049019f/basics-make-any-method-c.aspx. In summary it uses WaitOne with a timeout to determine if the call does not return before the timeout expires.
I also know that you should have an EndInvoke to match each BeginInvoke.
So what happens if the wait timeout expires? We (presumably) DON'T want to call EndInvoke as that will block. The code can go on to do 'other things', but have we leaked anything? Is there some poor thread someplace blocked waiting for a return that's never going to happen? Have we leaked some memory where the result-that-will-never-return was going to be placed?
I think this post talks about it very well:
From the post:
You can't terminate an executing async delegate if it's not your thread, but you can if it is. If you use the common BeginInvoke type methods, you get a thread pool thread managed by the framework. If you use the Thread() class you get you own thread to manage, start, suspend, etc. as you like.
Developing asychronously requires that one decide who will manage the threads. The many different methods that execute asynchronously are using the ThreadPool threads behind the scenes.
Since you can't/shouldn't terminate a thread pool thread then you must design you code to communicate with the thread so that it can exit. The MSDN examples for the BackgroundWorker component demonstrates this kind of communication.
Sometimes your code may have the thread blocking waiting for IO. Here you would normally use a multiple object wait instead, waiting for IO or for a ManualResetEvent.
So in short, youll need to find a way to manage the threads yourself if there is a possibility of timing out and you want the thread to end.
You need to call EndInvoke().
Here is a link talking about what happens with EndInvoke():
Is EndInvoke() optional, sort-of optional, or definitely not optional?
Here is a link to the article in the accepted answer.
We had all been talking about the 'fire and forget' technique with asynchronous delegate invocation in various public forums. Many DevelopMentor instructors had written articles and example code showing the technique, and we had all described it in class. And of course it was in Don's book by then too. So when Microsoft eventually remembered to let the outside world know that this technique is not in fact legal, it was rather astonishing.
An MSDN link on the asynchronous pattern.
You will leak the resources held by the thread. There will be various bits of .NET remoting plumbing objects like the AsyncResult. Several unmanaged handles associated with the thread. All peanuts compared to the one megabyte of virtual memory address space you'll leak, held by the thread stack.
You cannot abort the thread in any way, the leak is permanent. When you have to deal with badly behaving code like this, your only good resource is to run it in a separate process so you can get Windows to clean up the shrapnel when you shoot the process in the head with Process.Kill(). Even that is not guaranteed, these kind of freezes tend to be associated with misbehaving device drivers. Process.Kill won't terminate a device driver thread. Easy to see: trying to abort the process with Taskmgr.exe will leave it running with one Handle. You have some hope if that doesn't happen.

Categories

Resources