Information Technology Reference
In-Depth Information
// swap:
System.Threading. Interlocked .Exchange
< BindingList < PayrollData >>( ref data, updates);
}
}
There is a lot of boilerplate code to examine, and much of it is straight-
forward. However, there are a few important parts that you should exam-
ine with a bit more care. First, notice that a number of the members of the
IBindingList interface are implemented explicitly by the BindingList<T>
class. That is the reason for the casts included throughout many of the
methods. Also, I've coded this based on the PayrollData type being a value
type. If PayrollData was a reference type, this code would be a bit simpler.
I made PayrollData a value type to demonstrate those differences. The type
checks are based on that PayrollData being a value type (see Item 20).
Finally, notice that the ListChangedEventHandler must be implemented
explicitly so that you can forward the event handlers to the contained let-
ter object.
Of course, the point of this exercise was to create and implement the
SafeUpdate method. Notice that it does essentially the same work that you
did in place before. The only difference is that the swap is now accom-
plished by a call to Interlocked.Exchange. That guarantees that this code is
safe, even in multithreaded applications. The swap cannot be interrupted.
In the general case, you cannot fix the problem of swapping reference types
while still ensuring that all clients have the current copy of the object.
Swapping works for value types only. That should be sufficient, if you're
following the advice of Item 18.
Last, and most stringent, is the no-throw guarantee. The no-throw guar-
antee is pretty much what it sounds like: A method satisfies the no-throw
guarantee if it is guaranteed to always run to completion and never let an
exception leave a method. This just isn't practical for all routines in large
programs. However, in a few locations, methods must enforce the no-
throw guarantee. Finalizers and Dispose methods must not throw excep-
tions. In both cases, throwing an exception can cause more problems than
any other alternative. In the case of a finalizer, throwing an exception ter-
minates the program without further cleanup. Wrapping a large method
in a try / catch block and swallowing all exceptions is how you achieve
this no-throw guarantee. Most methods that must satisfy the no-throw
guarantee, such as Dispose() and Finalize(), have limited responsibilities.
 
Search WWH ::




Custom Search