15.02.2015 Views

C# 4 and .NET 4

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

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

s p in lock<br />

The SpinLock struct is new with .<strong>NET</strong> 4. If the overhead on object - based lock objects ( Monitor ) would<br />

be too high because of garbage collection, SpinLock can be used. SpinLock is useful if you have a high<br />

number of locks (for example, for every node in a list) <strong>and</strong> hold times are always extremely short. You<br />

should avoid holding more than one SpinLock <strong>and</strong> don ’ t call anything that might block.<br />

Other than the architectural differences, SpinLock is very similar in usage to the Monitor class. Acquiring<br />

the lock is done with Enter() or TryEnter() <strong>and</strong> releasing the lock with Exit() . SpinLock also offers<br />

properties to provide information if it is currently locked: IsHeld <strong>and</strong> IsHeldByCurrentThread .<br />

Be careful when passing SpinLock instances around. Because SpinLock is defi ned<br />

as a struct , assigning one variable to another creates a copy. Always pass SpinLock<br />

instances by reference.<br />

Wait h <strong>and</strong>le<br />

WaitH<strong>and</strong>le is an abstract base class that you can use to wait for a signal to be set. There are different<br />

things you can wait for, because WaitH<strong>and</strong>le is a base class <strong>and</strong> some classes are derived from it.<br />

When describing asynchronous delegates earlier in this chapter, the WaitH<strong>and</strong>le was already in use. The<br />

method BeginInvoke() of the asynchronous delegate returns an object that implements the interface<br />

IAsyncResult . Using IAsyncResult , you can access a WaitH<strong>and</strong>le with the property AsyncWaitH<strong>and</strong>le .<br />

When you invoke the method WaitOne() , the thread waits until a signal is received that is associated with<br />

the wait h<strong>and</strong>le.<br />

static void Main()<br />

{<br />

TakesAWhileDelegate d1 = TakesAWhile;<br />

}<br />

IAsyncResult ar = d1.BeginInvoke(1, 3000, null, null);<br />

while (true)<br />

{<br />

Console.Write(".");<br />

if (ar.AsyncWaitH<strong>and</strong>le.WaitOne(50, false))<br />

{<br />

Console.WriteLine("Can get the result now");<br />

break;<br />

}<br />

}<br />

int result = d1.EndInvoke(ar);<br />

Console.WriteLine("result: {0}", result);<br />

code snippet AsyncDelegate/Program.cs<br />

With WaitH<strong>and</strong>le , you can wait for one signal to occur ( WaitOne() ), multiple objects that all must be<br />

signaled ( WaitAll() ), or one of multiple objects ( WaitAny() ). WaitAll <strong>and</strong> WaitAny are static members of<br />

the WaitH<strong>and</strong>le class <strong>and</strong> accept an array of WaitH<strong>and</strong>le parameter.<br />

WaitH<strong>and</strong>le has a SafeWaitH<strong>and</strong>le property, where you can assign a native h<strong>and</strong>le to an operating<br />

system resource <strong>and</strong> wait for that h<strong>and</strong>le. For example, you can assign a SafeFileH<strong>and</strong>le to wait for a<br />

fi le I/O operation to complete, or a custom SafeTransactionH<strong>and</strong>le as shown in Chapter 23,<br />

“ System.Transactions. ”<br />

www.it-ebooks.info

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

Saved successfully!

Ooh no, something went wrong!