I’ve been working with multi-threaded programming since C# v1.0 with Visual Studio 2003. Before that, I have a few years working on multi-threaded programming in Java and C++.
There were a few things I hated on multi-threaded programming: imperative programming, implicit contract, and heavy thread composing; Thread interacting with WaitHandles like ManualResetEvent and AutoResetEvent; concerns about the race conditions, dead locks, live locks, thread starving etc. The last but not the least is the debugging. When there is something going wrong, it is really hard to debug without a good tool.
Task Parallel Library, or TPL, is a new .NET 4.0 new library, an component of the .NET 4.0 Parallel Frameworks. After I used it in my project, I felt Microsoft really hit the ball off the park this time.
TPL is EASY. TPL is just like the easy button. It is easy to use. It is easy to debug. It is easy to boost the performance of your application. If you have not started to use it in your project, I would strongly recommend you to start to use it or encourage your developers to use it.
Tasks vs Threads -> Tasks don’t equal to threads. You can think of Tasks are threads without all the threads’ drawbacks. Threads are single core, expensive on resources, such as 2M user mode memory plus kernel constructs. Thread needs time to startup and dispose. The most important is that the context switching the performance killer.
TPL is better in performance than using thread:
· Task scheduler has been highly optimized to utilize multi-processors with the brand new thread pool.
· There are less startup and tear down (mostly I/O) time for tasks than for threads.
· There is less time spending on context switching for tasks than for threads when threads are more than cores. Performance will degrade if the thread manager is not multi-core aware and thread running time aware.
· Memory (I/O) has been pre-allocated for the thread pool.
Here are some tips I learned to use TPL:
-- -- TPL Tips – Creating Task
· You can pass delegate to the constructor, either Action or Func. You can pass LINQ expression as well.
· You can create Task and run it right away. Or you can just create a task and declare it’s running condition.
· You can define TaskCreateOptions, such as LongRunning, or AttachedParent
· You can pass in Cancellation token.
-- -- TPL Tips – Passing data
· You can pass any object inherited from System.Object
-- -- TPL Tips – Returning
· This is way better than old TheadPool.QueueUserItem
-- -- TPL Tips – Waiting
· Waiting is a good way to declare parallelism
· Wait, WaitAll, WaitAny
-- -- TPL Tips – Cancelling
· Cancelling is cooperative
· CancellationTokenSource can be used once.
· Cancellation Token can be passed into task creation or waiting
· The beauty of the cancellation token is once the cancellation token source is cancelled, if the task has not been scheduled, it will not be executed.
-- -- TPL Tips – Continuing
· Task.ContinueWith
· Task.Factory.ContinueWhenAll()
· ContinuationOptions (OnlyOnFaulted, OnlyOnCancelled, NotOnRanToComplete)
· Continue with ParentTask.Result
-- -- TPL Tips – Composing
· AttachedToParent
8. -- TPL Tips – AggregateException
9 . -- TPL Tips – Cool Tools
· Parallel Tasks (see the location of code)
· Parallel Stacks (see the stack of the code)
What is hot in the coming releases in .NET 5.0?
Task DataFlow (TDF) – is based on Concurrency and Coordination Runtime and Visual C++ Asynchronous Agency 2010. Currently it is based on.
Visual Studio Async - async and await keywords. You can await anything, not only Task and Task.