15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Thread Pools ❘ 499<br />

The time quantum <strong>and</strong> round - robin principles are used only if multiple threads are running at the same<br />

priority. The priority is dynamic. If a thread is CPU - intensive (requires the CPU continuously without<br />

waiting for resources), the priority is lowered to the level of the base priority that is defi ned with the thread.<br />

If a thread is waiting for a resource, the thread gets a priority boost <strong>and</strong> the priority is increased. Because of<br />

the boost, there is a good chance that the thread gets the CPU the next time that the wait ends.<br />

With the Thread class, you can infl uence the base priority of the thread by setting the Priority property.<br />

The Priority property requires a value that is defi ned by the ThreadPriority enumeration. The levels<br />

defi ned are Highest , AboveNormal , Normal , BelowNormal , <strong>and</strong> Lowest .<br />

Be careful when giving a thread a higher priority, because this may decrease the chance<br />

for other threads to run. You can change the priority for a short time if necessary.<br />

Controlling Threads<br />

The thread is created by invoking the Start() method of a Thread object. However, after invoking the<br />

Start() method, the new thread is still not in the Running state, but in the Unstarted state. The thread<br />

changes to the Running state as soon as the operating system thread scheduler selects the thread to run. You<br />

can read the current state of a thread by reading the property Thread.ThreadState .<br />

With the Thread.Sleep() method, a thread goes into the WaitSleepJoin state <strong>and</strong> waits until it is woken<br />

up again after the time span defi ned with the Sleep() method has elapsed.<br />

To stop another thread, you can invoke the method Thread.Abort() . When this method is called, an<br />

exception of type ThreadAbortException is thrown in the thread that receives the abort. With a<br />

h<strong>and</strong>ler to catch this exception, the thread can do some cleanup before it ends. The thread also has<br />

a chance to continue running after receiving the ThreadAbortException as a result of invoking Thread.<br />

ResetAbort() . The state of the thread receiving the abort request changes from AbortRequested to the<br />

Aborted state if the thread does not reset the abort.<br />

If you need to wait for a thread to end, you can invoke the Thread.Join() method. Thread.Join() blocks<br />

the current thread <strong>and</strong> sets it to the WaitSleepJoin state until the thread that is joined is completed.<br />

Thread Pools<br />

Creating threads takes time. When you have different short tasks to do, you can create a number of threads<br />

in advance <strong>and</strong> send requests as they should be done. It would be nice if this number increased as more<br />

threads were needed <strong>and</strong> decreased as needed to release resources.<br />

There is no need to create such a list on your own. The list is managed by the ThreadPool class. This class<br />

increases <strong>and</strong> decreases the number of threads in the pool as they are needed, up to the maximum number<br />

of threads. The maximum number of threads in a pool is confi gurable. With a dual - core CPU, the default<br />

number is set to 1,023 worker threads <strong>and</strong> 1,000 I/O threads. You can specify the minimum number of<br />

threads that should be started immediately when the pool is created <strong>and</strong> the maximum number of threads<br />

that are available in the pool. If there are more jobs to process, <strong>and</strong> the maximum number of threads in the<br />

pool has already been reached, the newest jobs are queued <strong>and</strong> must wait for a thread to complete its work.<br />

The following sample application fi rst reads the maximum number of worker <strong>and</strong> I/O threads <strong>and</strong> writes<br />

this information to the console. Then, in a for loop, the method JobForAThread() is assigned to a thread<br />

from the thread pool by invoking the method ThreadPool.QueueUserWorkItem() <strong>and</strong> passing a delegate<br />

of type WaitCallback . The thread pool receives this request <strong>and</strong> selects one of the threads from the pool to<br />

invoke the method. If the pool is not already running, the pool is created <strong>and</strong> the fi rst thread is started. If<br />

the pool is already running <strong>and</strong> one thread is free to do the task, the job is forwarded to that thread.<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!