Monday, August 31, 2015

Brief about Multithreading

Asynchronous processing and background processing was always a must for serious programs serving complex user needs.

Threading design guidelines.
  1. Avoid providing static methods that mutate static state
  2. Design for server environment
  3. Instances do not need to be thread safe
  4. Static states must be thread safe
Timer threads
A common use of threads is for all kinds of periodical updates. Under Win32 we have two different ways: window timers and time limited waiting for events. .NET offers three different ways:

Windows timers with the System.WinForms.Timer class
Periodical delegate calling with System.Threading.Timer class (works on W2K only)
Exact timing with the System.Timers.Timer class

System.Timers.Timer class is the most complete solution for all time fired events. It gives you the most precise control and timing and is surprisingly simple to use.
  1. Create the Timer object. You can a use constructor with interval setting.
  2. Add your event handler (delegate) to the Tick event
  3. Set the Interval property to the desired number of milliseconds (default value is 100 ms)
  4. Set the AutoReset property to false if you want the event to be raised only once (default is true – repetitive raising)
  5. Start the ticking with a call to the Start() method, or by setting Enabled property to true.
  6. Stop the ticking with call to the Stop() method or by setting the Enabled property to false.

  using System.Timers ;   
  void TickHandler( object sender, EventArgs e ){   
    // do some work   
  }   
  // usage block   
  {   
    ...   
    // create timer   
    Timer kicker = new Timer() ;   
    kicker.Interval = 1000 ;   
    kicker.AutoReset = false ;   
    // add handler   
    kicker.Tick += new EventHandler( TickHandler ) ;   
    // start timer   
    kicker.Start() ;   
    // change interval   
    kicker.Interval = 2000 ;   
    // stop timer   
    kicker.Stop() ;   
    // you can start and stop timer againg  
      kicker.Start() ;  
      kicker.Stop() ;  
      ...  
 }  

I should mention a few things about using the Timers.Timer class:
  1. In VS Beta 1 you must add a reference to System.Timers namespace by hand.
  2. Whenever you use the Timers namespace together with System.WinForms or System.Threading, you should reference the Timer classes with the full name to avoid ambiguity.
  3. Be careful when using Timers.Timer objects. You may find them a lot faster than the old windows timers approach (think why). Do not forget synchronize data access.

Thread pooling

The idea for making a pool of threads on the .NET framework level comes from the fact that most threads in multithreaded programs spend most of the time waiting for something to happen. It means that thread entry functions contain endless loops which calls real working functions. By using the ThreadPool type object preparing working functions is simpler and for bonus we get better resource usage.

There are two important facts relating to ThreadPool object.
  1. There is only one ThreadPool type object per process
  2. There is only one working thread per thread pool object
The most useful use of a ThreadPool object is to add a new thread with a triggering event to the thread pool. i.e.. "when this event happens do this". For using ThreadPool this way you must perform following steps:
  1. Create event
  2. Create a delegate of type WaitOrTimerCallback
  3. Create an object which will carry status information to the delegate.
  4. Add all to thread pool
  5. Set event
// status information object
public class StatusObject{ // some information } // thread entry function public void someFunc( object obj, bool signaled ){ // do some clever work } // usage block { ... // create needed objects AutoResetEvent myEvent = new AutoResetEvent( false ) ; WaitOrTimerCallback myThreadMethod = new WairOrTimerCallback( someFunc ) ; StatusObject statusObject = new StatusObject() ; // decide how thread will perform int timeout = 10000 ; // timeout in ms bool repetable = true ; // timer will be reset after event fired or timeout // add to thread pool ThreadPool.RegisterWaitForSingleObject( myEvent, myThreadMethod, statusObject, timeout, repetable ) ; ... // raise event and start thread myEvent.Set() ; ... }

A less common use of a thread pool will be (or at least should be, be aware of misuse) adding threads to be executed when the processor is free. You could think of this kind of usage as "OK, I have this to do, so do it whenever you have time". Very democratic way of handling background processing which can stop your program quickly. Remember that inside the thread pool you have only one thread working (per processor).

Using thread pool this way is even simpler:
  1. Create a delegate of type WaitCallback
  2. Create an object for status information, if you need it
  3. Add to thread pool

// status information object  
 public class StatusObject{  
      // some information  
 }  
 // thread entry function  
 public void someFunc( object obj, bool signaled ){  
      // do some clever work  
 }  
 // usage block  
 {  
      ...  
      // create needed objects  
      WaitCallback myThreadMethod = new WairOrTimerCallback( someFunc ) ;  
      StatusObject statusObject = new StatusObject() ;  
      // add to thread pool  
      ThreadPool.QueueUserWorkItem( myThreadMethod, statusObject ) ;  
      ...  
 }  

Some notes on thread pool:
  1. Don’t use a thread pool for threads that perform long calculations. You only have one thread per processor actually working.
  2. System.Thread.Timer type objects are one thread inside thread pool
  3. You have only one thread pool per process

No comments:

Post a Comment

Code Formater

Paste Here Your Source Code
Source Code Formatting Options
1) Convert Tab into Space :
2) Need Line Code Numbering :
3) Remove blank lines :
4) Embeded styles / Stylesheet :
5) Code Block Width :
6) Code Block Height :
7) Alternative Background :
Copy Formatted Source Code
 
Preview Of Formatted Code