Coming from python background where we have:
Multiprocessing- to run multiple tasks in parallel on the processors - ideal for cpu bound tasks.
Multi threading- to run multiple tasks in parallel via threads within a single processor. Ideal for io bound tasks. Io bound only because of presence of GIL which results in only 1 thread being able to use the processor at any point in time.
Async await- to do cooperative programming for io bound tasks.
Using python code I can achieve either of the above.
In the case of c# I am learning that: We can either start threads explicitly or use concept of async await and Task.Run that implicitly handles the threads creation and management.
Async await is good for io bound tasks. Async await + Task.Run is good for cpu bound tasks.
In windows forms app we have the concept of synchronization context which ensures that only the single Ui thread runs all the code.
However if we use async await + Task.Run (which is good for cpu bound tasks), then the code inside Task.Run will run in separate thread.
Either ways code below the await will run on ui thread.
Where as in console app, whether we use async await or async await + Task.Run, code after the await will be run by multiple threads (from threadpool) in parallel due to the absence of synchronization context. An example of this is shown here: In console app, why does synchronous blocking code (Thread.Sleep(..)) when used in an awaited async task behave like multi threading?
In c#, threads are derived from the threadpool (I think that there is one thread per processor core, please correct me). However, unlike python, we don't have control to run code explicitly to target single or certain number of processors in c# do we?