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.

512 ❘ ChaPTer 20 threAds, tAsks, And synchrOnizAtiOn<br />

occur more often than with a single-core CPU. The<br />

problem will occur with a single-core CPU because<br />

thread scheduling is preemptive, but not that often.<br />

Figure 20-1 shows an assertion of the program,<br />

where the race condition occurred after 75,069<br />

loops. You can start the application multiple times,<br />

<strong>and</strong> you will always get different results.<br />

You can avoid the problem by locking the shared<br />

object. You can do this inside the thread by<br />

locking the variable state, which is shared among<br />

the threads, with the lock statement as shown.<br />

Only one thread can be inside the lock block for<br />

the state object. Because this object is shared<br />

among all threads, a thread must wait at the lock<br />

if another thread has the lock for state. As soon as<br />

the lock is accepted, the thread owns the lock <strong>and</strong><br />

gives it up with the end of the lock block. If every<br />

thread changing the object referenced with the<br />

state variable is using a lock, the race condition no<br />

longer occurs.<br />

figure 20-1<br />

public class SampleTask<br />

{<br />

public void RaceCondition(object o)<br />

{<br />

Trace.Assert(o is StateObject, "o must be of type StateObject");<br />

StateObject state = o as StateObject;<br />

}<br />

}<br />

int i = 0;<br />

while (true)<br />

{<br />

lock (state) // no race condition with this lock<br />

{<br />

state.ChangeState(i++);<br />

}<br />

}<br />

code snippet ThreadingIssues/SampleTask.cs<br />

Instead of performing the lock when using the shared object, you can make the shared object thread-safe.<br />

Here, the ChangeState() method contains a lock statement. Because you cannot lock the state variable<br />

itself (only reference types can be used for a lock), the variable sync of type object is defined <strong>and</strong> used<br />

with the lock statement. If a lock is done using the same synchronization object every time the value state is<br />

changed, race conditions no longer happen.<br />

public class StateObject<br />

{<br />

private int state = 5;<br />

private object sync = new object();<br />

public void ChangeState(int loop)<br />

{<br />

lock (sync)<br />

{<br />

if (state == 5)<br />

{<br />

www.it-ebooks.info

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

Saved successfully!

Ooh no, something went wrong!