C# Threads

             Jim Fawcett
CSE681 – Software Modeling and Analysis
               Fall 2005
Thread Class

•   Every Win32 thread is passed a function to run when created.

    – When the thread returns from the function it terminates.

•   In C#, Threads are managed by the System.Threading.Thread
    class.

    – C# threads are passed a static or instance function of some C#
      class using a standard delegate of type ThreadStart.
Starting C# Threads

•   Thread thread =
       new Thread(new ThreadStart(ThreadFunc));

•   thread.Start();

•   ThreadFunc can be:
    – Static or instance member of the class instance that created the thread
    – Static or instance member of some other class, e.g.:

       ThreadStart(SomeClass.aStaticFunction);
       ThreadStart(someClassInstance.aNonStaticFunction);
Thread States

•   A thread that has been started, but not yet terminated can be in
    one of the following states:
     –   Running
     –   Waiting to run
     –   Suspended
     –   Blocked
Thread Properties

•   IsBackground – get, set
     – Process does not end until all Foreground threads have ended.
     – Background threads are terminated when application ends.
•   CurrentThread – get, static
     – Returns thread reference to calling thread

•   IsAlive – get
     – Has thread started but not terminated?

•   Priority – get, set
     – Highest, AboveNormal, Normal, BelowNormal, Lowest
•   ThreadState – get
     – Unstarted, Running, Suspended, Stopped, WaitSleepJoin, ..
Sharing Resources

•   A child thread often needs to communciate with its parent thread. It does
    this via some shared resource, like a queue.


                              Parent Thread


                     Sending Message to Child




                                                               Child Thread


                                                Shared Queue


                                                               Receiving Message from
                                                                       Parent
Synchronization

•   When two or more threads share a common resource access needs
    to be serialized - a process called synchronization.
    – Consider the shared queue on the previous slide. Should the parent
      start to enqueue an element in an empty queue, but have its time-slice
      expire before finishing, the queues links are in an undefined state.

    – Now, if the child thread wakes up, and attempts to dequeue an element
      the result is undefined.
Synchronization with C# Lock

// send messages to child thread

     string msg = "";
     for(int i=0; i<50; ++i)
     {
       msg = "message #" + i.ToString();
       Console.Write("n Sending {0},",msg);

         // Enqueuing changes links so must lock

         lock(demo.threadQ) { demo.threadQ.Enqueue(msg); }

         // control writer speed - twice as fast as reader

         Thread.Sleep(50);
     }

     lock(demo.threadQ) { demo.threadQ.Enqueue("end"); }

     child.Join();
     Console.Write(
       "nn child thread state = {0}nn",child.ThreadState.ToString()
     );
Demonstration Program

•   QueuedMessages folder

    – Illustrates communication between parent and child threads using a
      queue.

    – Also illustrates use of C# lock operation.
Other Locking Mechanisms

•   The .Net Threading Library also provides:

     – Monitor
         • Locks an object, like C# lock, but provides more control.
     – Interlocked
         • Provides atomic operations on 32 bit and 64 bit data types, e.g., ints,
           longs, pointers.
     – Mutex
         • Guards a region of code.
         • Can synchronize across process boundaries.
     – AutoResetEvent and WaitOne
         • Allows fine-grained control of the sequencing of thread operations.
     – ReaderWriterLock
         • Locks only when writing, allowing free reads.
Locking Certain Collections

•   ArrayList, Hashtable, Queue, Stack, and other collections provide
    Synchronized() function, supporting high performance locking.

       ArrayList unsync = new ArrayList();
       ArrayList sync = ArrayList.Synchronized(unsynch);

    Your code needs no lock constructs with sync.
Method Decoration

•   Methods can be decorated with a MethodImpl attribute, synchronizing
    access much like a Win32 critical section.

      [MethodImpl (MethodImplOptions.Synchronized)]
       string myMethod(string input)
       {
           …
       }

    Note that this synchronizes a region of code, while lock and Monitor
    synchronize objects.
WinForms and Worker Threads

•   A UI thread is a thread that creates a window. A worker thread
    is a thread spawned by a UI thread to do work in the
    background while the UI thread services UI messages.

•   A worker thread must never access UI functions directly. It
    accesses them through Form’s Invoke, BeginInvoke, and
    EndInvoke functions, passing a delegate as an argument.
BeginInvoke Example

for (i = 1; i <= 25; i++)
{
  s = "Step number " + i.ToString() + " executed";
  Thread.Sleep(400);

    // Make asynchronous call to main form.

    //   MainForm.AddString function runs in main thread
    //   because we activated the delegate through form's
    //   Invoke (synchronous) or BeginInvoke (asynchronous) functions.
    //   To make synchronous call use Invoke.

    m_form.BeginInvoke(m_form.m_DelegateAddString, new Object[] {s});

    // check if thread is cancelled
    if ( m_EventStop.WaitOne(0, true) )
    {
      // clean-up operations may be placed here
      // ...                                                      Delegate arguments
                                                                  passed as an array of
        // inform main thread that this thread stopped
        m_EventStopped.Set();                                     objects
        return;
    }
}
Demonstration Programs

•   ProcessDemo and ProcessDemoWin32
    – Illustrates creating a child process
•   QueuedMessages
    – Illustrates communication between threads using queues and the
      C# lock operation.
•   FormInvokeDemo folder
    – A more interesting demonstration of the above.
•   WorkerThread folder
    – Simple Demonstration of UI and Worker thread communication
      using Form.Invoke(…)
•   ThreadPoolDemo folder
    – Illustrates how to use the ThreadPool to run functions
End of Presentation