Is EndInvoke() optional, sort-of optional, or definitely not optional?
Delegate.EndInvoke is documented as a thou shalt call this (i.e. necessary - else leaks happen) - from msdn:
Important Note
No matter which technique you use, always call EndInvoke to complete your asynchronous call.
Control.EndInvoke is OK to ignore for fire-and-forget methods - from msdn:
You can call EndInvoke to retrieve the return value from the delegate, if neccesary, but this is not required.
However - if you are using Delegate.BeginInvoke
and don't want the result, consider using ThreadPool.QueueUserWorkItem
instead - it'll make life a lot easier, and avoid the pain of IAsyncResult
etc.
And EndInvoke call is not optional call, it is a part of the contract. If you call BeginInvoke you must call EndInvoke.
Classic example of why this is necessary. It's very possible that the IAsyncResult returned from BeginInvoke has allocated resources attached to it. Most commonly a WaitHandle of sorts. Because IAsyncResult does not implement IDisposable another place must be chosen to free the resources. The only place to do so is EndInvoke.
I briefly discuss this problem in the following blog post.
http://blogs.msdn.com/jaredpar/archive/2008/01/07/isynchronizeinvoke-now.aspx