Difference between TPL and async / await (Stream Processing)

Trying to understand the difference between TPL and async / await when it comes to thread creation.

I believe that TPL (TaskFactory.Startnew) works like ThreadPool.QueueUserWorkItem in that it queues up work on a thread in a thread pool. Of course, if you are not using TaskCreationOptions.LongRunning, which create a new thread.

I thought async / await would work just as much:

TPL:

Factory.StartNew( () => DoSomeAsyncWork() ) .ContinueWith( (antecedent) => { DoSomeWorkAfter(); },TaskScheduler.FromCurrentSynchronizationContext()); 

Asynchronous / Await:

 await DoSomeAsyncWork(); DoSomeWorkAfter(); 

will be identical. From what I read, it seems that async / await only "sometimes" creates a new thread. So when does it create a new thread and when does it not create a new thread? If you were dealing with IO I / O ports, I see that you do not need to create a new thread, but otherwise I would think that it is necessary. I think my understanding of FromCurrentSynchronizationContext has always been a bit fuzzy. I always understood that it was, in fact, a UI thread.

+48
multithreading task-parallel-library async-await
Apr 23 2018-12-12T00:
source share
2 answers

I believe that TPL (TaskFactory.Startnew) works similarly to ThreadPool.QueueUserWorkItem in that it pauses work on a thread in the thread pool.

Quite a lot .

From what I read, it seems that async / await only "sometimes" creates a new thread.

Actually, this never happens. If you want multithreading, you must implement it yourself. There is a new Task.Run method that is simply abbreviated for Task.Factory.StartNew , and this is probably the most common way to start a task in a thread pool.

If you were dealing with IO I / O ports, I see that you do not need to create a new thread, but otherwise I would have thought it would be necessary.

Bingo. Thus, methods like Stream.ReadAsync will actually create a Task wrapper around IOCP (if Stream has IOCP).

You can also create some tasks other than I / O, non-CPU. A simple example is Task.Delay , which returns a task that completes after a period of time.

The nice thing about async / await is that you can order some work in the thread pool (e.g. Task.Run ), perform some operation with I / O binding (e.g. Stream.ReadAsync ) and do some other operation (e.g. , Task.Delay ) ... and that's all the tasks! They can be expected or used in combinations such as Task.WhenAll .

Any method that returns Task can be await ed - it should not be async . Thus, Task.Delay and I / O bindings simply use TaskCompletionSource to create and complete the task - the only thing that is done in the thread pool is the actual completion of the task when an event occurs (timeout, I / O completion, etc.) d.).).

I think my understanding of FromCurrentSynchronizationContext has always been a bit fuzzy. I always understood that it was, in fact, a UI thread.

I wrote an article in SynchronizationContext . Most of the time, SynchronizationContext.Current :

  • is a user interface context if the current thread is a user interface thread.
  • is the context of the ASP.NET request if the current thread is serving the ASP.NET request.
  • is the context of the thread pool otherwise.

Any thread can set its own SynchronizationContext , so there are exceptions to the rules above.

Note that awaiter Task by default schedule the remainder of the async method for the current SynchronizationContext if it is not null; otherwise, it goes to the current TaskScheduler . Today it is not so important, but in the near future it will be an important difference.

I wrote my own async / await intro on my blog, and Stephen Tub recently posted an excellent async / await FAQ .

For "concurrency" and "multithreading," see this related SO question . I would say that async includes concurrency, which may or may not be multithreaded. It is easy to use await Task.WhenAll or await Task.WhenAny for parallel processing, and if you are not explicitly using a thread pool (e.g. Task.Run or ConfigureAwait(false) ), then you can perform several simultaneous operations at the same time (for example, several input operations output or other types, such as Delay ), and there is no need for a stream. I use the term "single-threaded concurrency" for this kind of scenario, although on an ASP.NET host you can actually "zero-thread concurrency". This is pretty sweet.

+61
Apr 23 '12 at 18:56
source share

async / await basically simplifies ContinueWith methods (Continuations in Continuation style )

Concurrency is not entered into it - you still need to do it yourself (or use the Async version of the framework method.)

So, the C # 5 version will be:

 await Task.Run( () => DoSomeAsyncWork() ); DoSomeWorkAfter(); 
+8
Apr 23 2018-12-12T00:
source share



All Articles