What happens if a client does not call End?
If is up to the supplier of the IAsyncResult to cleanup when the IAsyncResult object is finalized.
Can the same instance of a callback object be passed to multiple calls simultaneously? (Assuming of course that is stateless with respect to the calls being made)
Yes.
Does an async server always need to provide a WaitHandle in IAsyncResult or Does the design pattern mandate that a server which provides its own asynchronous processing always provide a wait handle in its implementation of IAsyncResult? Is it legal to return null from IAsyncResult.WaitHandle?
The provider of the asyncresult must supply a wait handle, but you can wait until it is requested and fault it in at that time.