C# Threads
Jim Fawcett
CSE681 – Software Modeling & Analysis
Fall 2002
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
[Link] 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));
[Link]();
ThreadFunc can be:
Static or instance member of the class instance that
created the thread
Static or instance member of some other class
It must have the signature:
void myThreadFunc();
You can supply parameters for thread operation as
member data of the ThreadFunc’s class.
Examples of ThreadStart
ThreadFunc is a static member of TFClass:
Thread thread = new ThreadStart([Link])
ThreadFunc is a non-static member of TFClass:
TFClass tfc;
Thread thread = new ThreadStart([Link]);
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 #" + [Link]();
[Link]("\n Sending {0},",msg);
// Enqueuing changes links so must lock
lock([Link]) { [Link](msg); }
// control writer speed - twice as fast as reader
[Link](50);
}
lock([Link]) { [Link]("end"); }
[Link]();
[Link](
"\n\n child thread state = {0}\n\n",[Link]()
);
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 =
[Link](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 ([Link])]
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 " + [Link]() + " executed"; Delegate arguments
[Link](400);
passed as an array of
// Make asynchronous call to main form. objects
// [Link] function runs in main thread
// because we activated the delegate through form's
// BeginInvoke function.
// 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
// ...
// inform main thread that this thread stopped
m_EventStopped.Set();
return;
}
}
Demonstration Programs
ProcessDemo
Illustrates creating a child process
Worker Thread folder
Simple Demonstration of UI and Worker thread
communication using [Link](…)
FormInvokeDemo folder
A more interesting demonstration of the above.
QueuedMessages
Illustrates communication between threads using
queues and the C# lock operation.
End of Presentation