Is EndInvoke() optional, sort-of optional, or definitely not optional?
Asked Answered
B

7

56

I've read conflicting opinions as to whether every BeginInvoke() has to be matched by an EndInvoke(). Are there any leaks or other problems associated with NOT calling EndInvoke()?

Bisset answered 10/2, 2009 at 15:10 Comment(1)
You might also want to see: marcgravell.blogspot.com/2009/02/async-without-pain.htmlIschium
I
53

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.

Ischium answered 10/2, 2009 at 15:14 Comment(2)
Thanks Marc, that's what motivated the question - I was looking through Richter and noticed QueueUserWorkItem, and thought "hang on, why am I using BeginInvoke/EndInvoke elsewhere".Bisset
@Bisset - indeed: most BeginInvoke usage can be done more simply with ThreadPool; the BeginInvoke is perhaps useful for doing a few things and gathering them back again afterwards...Ischium
D
18

EndInvoke is not optional.

More info here

Dumfries answered 10/2, 2009 at 15:13 Comment(2)
... for delegates, at least ;-pIschium
from your link : "The only documented exception to the rule that I'm aware of is in Windows Forms, where you are officially allowed to call Control.BeginInvoke without bothering to call Control.EndInvoke."Blubbery
T
9

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

Tonality answered 10/2, 2009 at 15:14 Comment(0)
H
4

EndInvoke is not optional because it is the place where exceptions are thrown if something went wrong in the asyncronous processing.

Anyway there should not be any leak because if the IAsyncResult is holding some native resource it should correctly implement IDisposable and dispose such resources when the GC calls his finalizer.

Halfbound answered 10/2, 2009 at 15:26 Comment(0)
C
3

It is not optional because calling BeginInvoke makes use of a WaitHandle which in turns makes use of a kernel object that maintains a count for how many references are had to it. Calling EndInvoke gracefully disposes the handle which decrements that counter on the kernel object and when that count reaches zero, the kernel object manager will destroy it.

Coordinate answered 10/2, 2009 at 16:1 Comment(0)
P
2

Its only optional if you don't mind your program's memory growing very large. The issue is that the GC is holding onto all of the references in your thread, because you might want to call EndInvoke at some point. I would go with Marc's answer, the threadpool will make your life easier. However, you need to watch out if you spawn threads from your threads, as it is limited in the number of threads it can spin up.

Personage answered 10/2, 2009 at 15:38 Comment(0)
G
2

Every reply on this post says that EndInvoke() is not optional. However, I found the following highly ranked comment that is the accepted answer on this SO thread:

"Note that the Windows Forms team has guaranteed that you can use Control.BeginInvoke in a 'fire and forget' manner - i.e. without ever calling EndInvoke. This is not true of async calls in general: normally every BeginXXX should have a corresponding EndXXX call, usually in the callback."

What's the difference between Invoke() and BeginInvoke()

Glioma answered 18/12, 2012 at 18:12 Comment(2)
IMHO, it's too bad that Control.BeginInvoke and Delegate.BeginInvoke share the same name, since they have totally different semantics; truth be told, I'm curious as to why delegate types define BeginInvoke is an instance method , rather than having Delegate.Bind(params) return a MethodInvoker [zero-argument delegate] which would invoke the delegate with the specified parameters, and which could be passed to e.g. a ThreadPool.BeginInvoke method.Rootlet
+1 for this important distinction. The all-knowing Skeet's comment (quoted above) is highly relevant for those considering Control.InvokeRequired situations.Sadowski

© 2022 - 2024 — McMap. All rights reserved.