There is an internal discussion around IAsyncResult implmentation, and the developer responsible for IAsyncResult posted all the invariants that a compliant implementation has to support.
Posted below for your information:
Sent: Monday, March 27, 2006 4:28 PM
Subject: RE: IAsyncResult implementation
A while back we did a project to lay out all the invariants that a compliant implementation has to support. These are both necessary and sufficient, and are from the point of view of the IAsyncResult consumer. (That is, as long as the properties behave this way, it doesn’t matter what the implementation is.)
1. IsCompleted can change from false to true, but never from true to false.
2. CompletedSynchronously never changes.
3. If CompletedSynchronously is true, IsCompleted is true.
4. If AsyncWaitHandle is signaled, IsCompleted is true.
5. If queried from within the callback, AsyncWaitHandle is signaled.
6. EndXxx doesn’t block if IsCompleted is true.
7. The callback is called exactly once, unless BeginXxx throws, in which case it isn’t called.
8. AsyncWaitHandle is valid (not disposed) until EndXxx is called.
9. The same instance of IAsyncResult is returned from BeginXxx and passed into the callback.
10. BeginXxx doesn’t block.
11. AsyncState returns the state object passed to BeginXxx.