C-Asynchronous Approachs

There are several ways to implement multithreading and asynchronous operation in any application, This page will help you in decision making of when to use what. I won`t be covering how to implement theses approach because lot of study materials are already available in public domain. however in case study section will cover some of them.

Content presented below is consolidation of my understanding about threading and asynchronous operation from a solution architecture view point.

Table : Selecting best asynchronous(multithreading) Approach

 ASync Approach            
Applicability
 Discussion
 GUI Thread UI,Form Based Application Most of the time we do not explicitly use GUI thread because it is once per application and created by windows.
 Application.DoEvent UI,Form Based Application,
  • If you are doing some long task on main GUI thread such as downloading a file stream that is actually performed in the loop of small steps such as copy buffer then call Application.DoEvent in inner loop of your code that will keep your UI responsive without use of thread.
  • But if your code is making a long haul blocking call such as FIle.Copy that can not interrupted in between then either go for dedicated thread or thread pool.
 Timer Anywhere
Typical Uses : Timers are favorite solution if some periodic task need to be performed such as server cleanup, regular download of a file. However downside is that timer do not provide any mechanism for getting progress updated or cooperative cancellation but it is possible to do workaround with some well proven design pattern.
  • It has several performance benefit because internally it uses CLR thread pool.
  • Types of Timers
    • Form.Timer : Pushes the task in main GUI thread , avoid it if task will take to long to process other wise it will block UI.
    • DispatcherTimer : Equivalent to Forms.Timer but used in WPF and Silverlight applications.
    • Thread.Timer: Pushes the task in thread pool associated with application, it is most recommended way of using timer.
    • System.Timer : Wrapper over Thread.Timer bit simplified but prefer using system.timer because it is technically obsolete.
Delegate.BeginInvoke  Anywhere

Typical Uses : If you need to execute same type of function again and again and above approaches do not fit in your requirement consider Delegate before moving this point forward.

  • Delegates are type-safe function pointers that allow you to call methods with the same signature.
    It can be called call methods either synchronously by using the delegate’s Invoke method, or asynchronously by using BeginInvoke and EndInvoke.
  • When BeginInvoke is called, an operation specified by the delegate is started on a separate thread. You can retrieve the result of the operation by calling EndInvoke, which will block the calling thread until the background process is completed. You can also specify a callback method to complete the operation on the background thread if the result is not needed by the main thread.
Dedicated Foreground Thread  Anywhere Foreground Threads can not be canceled by OS and there is only solution when we should think of using foreground thread as listed below.
  • Your application need to executed a long haul job that must be either complete or canceled
  • Main thread can not be freezes and it need to keep track of execution going on child thread.
Usually we should avoid using dedicated thread as a whole because of management and performance overhead.
Background Worker Thread  Anywhere Technically there is no difference in background and foreground threads other that the fact that background thread will be terminated by OS at the time of application shutdown.

Just like Foreground Thread we should avoid using dedicated background thread as a whole because of management and performance overhead.However in some situation we may prefer dedicated background thread.
  • We just 1-2 thread but for very long duration that are supposed to do periodic jobs such as downloading feeds.
  • There is really no harm if OS terminated the thread in between during application shutdown.  
Thread Pool  Anywhere This is real sweet corn provided by CLR that offload a lot of management and performance overhead from developers shoulders.By design it implement Fire and Forgot Strategy that means just handover the job and forgot how it will be executed , how many thread will be created etc. Below are some typical situation when thread pool will be preferred
  • Application has to frequently execute small amount of work such as responding to http request. 
  • When we need to split the task on multiple threads such a large file can be downloaded in multi part using several threads reducing overall time. Most of download manager use this strategy.
  • There is no significant loss if OS terminated the thread in between at the time of shutdown because thread pool uses background thread.
  • You do not want to keep track of thread creation and disposal.
Task  Anywhere Task is an alternative to ThreadPool and have several additional feature over the ThreadPool.
  • It has built-in mechanism for progress update, cancellation, and wait support. Additionally it offers Task Factories that allow you to create a group of task sharing common state data.
  • Task infrastructure also offer a Task Scheduler that provides ThreadPool like experience and also support future triggering  of task
  • On the top of above it also has task chaining property that allow triggering of next task when one is finished
  • From Programming side it offers construct like Parallel- For and Parallel-ForEach that makes multithreading easier on collections or collection of task
Typical Uses Scenario
Task has higher overhead that thread pool after all it is written on the top of it. below is the some common uses sacenerios
  • You need to download multiple files from internet and need to keep UI updated.
  • You need to build chain of task for processing a data in multiple stages (Processing pipeline )
  • Have a long list of work items in a collection that need to be process in async way while keeping track of each of them individually.
Note :- Most of the feature offered by Task can also be achieved by thread pool we properly design our threading model and uses right design pattern. I will take them to a separate article  

Job  Anywhere  A job object allows groups of processes to be managed as a unit. Job objects are namable, securable, sharable objects that control attributes of the processes associated with them. Operations performed on the job object affect all processes associated with the job object.
 Fiber Any where
 A fiber is a unit of execution that must be manually scheduled by the application. Fibers run in the context of the threads that schedule them
 User-mode scheduling (UMS) Only on Multicore Multiprocessor and 64 bit systems only.
  •  It is a lightweight mechanism that applications can use to schedule their own threads. UMS threads differ from fibers in that each UMS thread has its own thread context instead of sharing the thread context of a single thread.
  • The ability to switch between threads in user mode makes UMS more efficient than thread pools for managing large numbers of short-duration work items that require few system calls. 
  • UMS is recommended for applications with high performance requirements that need to efficiently run many threads concurrently on multiprocessor or multicore systems. To take advantage of UMS, an application must implement a scheduler component that manages the application's UMS threads and determines when they should run.
  • If Application performance requirements justify the work involved in developing such a component. Applications with moderate performance requirements might be better served by allowing the system scheduler to schedule their threads.
  • Limitation UMS is available for 64-bit applications running on 64-bit versions of Windows 7 and Windows Server 2008 R2 or later 64-bit versions of Windows. This feature is not available on 32-bit versions of Windows. Read More... or  watch  Channel-9

Comments