The System.Threading namespace provides a wealth of classes and interfaces to manage multi-threaded programming;
Creating Threads:
The simplest way to create a thread is to create a new instance of the Thread class.The Thread constructor takes a single argument: a delegate instance. The CLR provides the ThreadStart delegate class specifically for this purpose, which points to a method you designate. This allows you to construct a thread and to say to it, “When you start, run this method.”
The ThreadStart delegate declaration is:
public delegate void ThreadStart( );As you can see, the method you attach to this delegate must take no parameters and must return void. Thus, you might create a new thread like this:
Thread myThread = new Thread( new ThreadStart(myFunc) ); myThread.Start( ); //starts thread executionWhere myFunc looks like (returns void and takes no parameters):
public void myFunc(){ (...) }
Waiting for other threads to finish execution
This can be acomplished by calling:myThread.Join( );
Example if you have a list of threads and the current thread needs to wait till they finish execution:
foreach (Thread myThread in myThreads) { myThread.Join( ); } Console.WriteLine("All my threads are done.");
Halting thread execution
Thread.Sleep(100); //halts execution for 100 milliseconds /* NOTE:the zero value is a special case that signals the thread scheduler that you’d like your thread to yield to another thread, even if the thread scheduler might otherwise give your thread a bit more time: */ Thread.Sleep(0);
Killing a thread
Typically, threads die after running their course but there are multiple ways to force stop a thread:- You can ask a thread to kill itself. The cleanest way is to set a KeepAlive Boolean flag that the thread can check periodically. When the flag changes state (e.g., goes from true to false), the thread can stop itself;
- an alternative is to call Thread.Interrupt, which asks the thread to kill itself;
- in desperation, and if you are shutting down your application in any case, you may
call Thread.Abort. This causes a ThreadAbortException exception to be thrown, which
the thread can catch.
Synchronizing threads
Synchronization is provided by a lock on the object, which helps the developer avoid having a second thread barge in on your object until the first thread is finished with it.The CLR provides a number of synchronization mechanisms. These include the common synchronization tools such as critical sections (called locks in .NET), as well as the Monitor class:
- Interlocked class: is a special class only usefull to increment/decrement variables in a synchronized manner.
int temp = Interlocked.Increment(ref counter);
These methods have some overloads making it possible to operate with int, floats, etc.
- The C# lock keyword is a more general synchronization mechanism.
A lock marks a critical section of your code, providing synchronization to an object you designate while the lock is in effect.
Example (calling this inside an object, the "counter" variable simulates a shared resource):
int temp; lock (this) { temp = counter; temp++; Thread.Sleep(1); //no problem no other thread will achieve //the resource till the block is over counter = temp; } Console.WriteLine("Thread {0}. Incrementer: {1}", Thread.CurrentThread.Name, temp);
Example2:
class Program { private int counter; static void Main(string[] args) { Program p = new Program(); Thread t1 = new Thread(new ThreadStart(p.Increment)); t1.Name = "t1"; Thread t2 = new Thread(new ThreadStart(p.Increment)); t2.Name = "t2"; t1.Start(); t2.Start(); Console.WriteLine("Main thread finished execution"); Console.ReadKey(); } private void Increment() { int temp; for (int i = 0; i < 5; i++) { lock(this){ temp = counter; temp++; Thread.Sleep(0); counter = temp; } Console.WriteLine("{0}:{1}",Thread.CurrentThread.Name, counter); Thread.Sleep(0); } Console.WriteLine("Thread {0} finished execution", Thread.CurrentThread.Name); } } /*OUTPUT: Main thread finished execution t1:1 t2:2 t1:3 t2:4 t1:5 t2:6 t1:7 t2:8 t1:9 Thread t1 finished execution t2:10 Thread t2 finished execution */
Note: the inner "Thread.Sleep(0)" wont do nothing since the other thread is waiting for the locked resource. The outer "Thread.Sleep(0)" is making the Threads achieve the resource in an alternate way;
No comments:
Post a Comment