15.01.2013 Views

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

SHOW MORE
SHOW LESS

Create successful ePaper yourself

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

For a discussion as to why aborting .NET Framework code is<br />

not safe, see the topic “Aborting Threads” at http://www.alba<br />

hari.com/threading/.<br />

There are two cases, though, where you can safely use Abort. One is if you are willing<br />

to tear down a thread’s application domain after it is aborted. A good example of<br />

when you might do this is in writing a unit-testing framework. (We discuss application<br />

domains fully in Chapter 24.) Another case where you can call Abort safely<br />

is on your own thread (because you know exactly where you are). Aborting your<br />

own thread throws an “unswallowable” exception: one that gets rethrown after each<br />

catch block. ASP.NET does exactly this when you call Redirect.<br />

Safe Cancellation<br />

LINQPad aborts threads when you cancel a runaway query. After<br />

aborting, it dismantles and re-creates the query’s application<br />

domain to avoid the potentially polluted state that could<br />

otherwise occur.<br />

As we saw in the preceding section, calling Abort on a thread is dangerous in most<br />

scenarios. The alternative, then, is to implement a cooperative pattern whereby the<br />

worker periodically checks a flag that indicates whether it should abort (like in<br />

BackgroundWorker). To cancel, the instigator simply sets the flag, and then waits for<br />

the worker to comply. This BackgroundWorker helper class implements such a flagbased<br />

cancellation pattern, and you easily implement one yourself.<br />

The obvious disadvantage is that the worker method must be written explicitly to<br />

support cancellation. Nonetheless, this is one of the few safe cancellation patterns.<br />

To illustrate this pattern, we’ll first write a class to encapsulate the cancellation flag:<br />

class RulyCanceler<br />

{<br />

object _cancelLocker = new object();<br />

bool _cancelRequest;<br />

public bool IsCancellationRequested<br />

{<br />

get { lock (_cancelLocker) return _cancelRequest; }<br />

}<br />

public void Cancel() { lock (_cancelLocker) _cancelRequest = true; }<br />

public void ThrowIfCancellationRequested()<br />

{<br />

if (IsCancellationRequested) throw new OperationCanceledException();<br />

}<br />

}<br />

Safe Cancellation | 857<br />

Threading

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

Saved successfully!

Ooh no, something went wrong!