I'm not sure I understand the ramifications of your answer. Let me change
the question slightly and see what shakes out. Suppose I have a class that
provides its own BeginXxx/EndXxx implementation:
Class Test
Public Sub DoWork()
' <Perform some long-running operation>
End Sub
Private _deleg As New TestDelegate(AddressOf DoWork)
Public Function BeginDoWork( _
ByVal callback As AsyncCallback, ByVal state As Object) As IAsyncResult
Return _deleg.BeginInvoke(callback, state)
End Function
Public Sub EndDoWork(asyncResult As IAsyncResult)
_deleg.EndInvoke(asyncResult)
End Sub
End Class
Now, my main program does the following:
Dim test As New Test
test.BeginDoWork(Nothing, Nothing)
test = Nothing
Does something keep the (now abandoned) Test instance alive forever (since
I'm never calling the delegate's EndInvoke)?
> Does something keep the (now abandoned) Test instance alive forever (since
> I'm never calling the delegate's EndInvoke)?
Actually, I was in a bit of a rush to get out the door to an
appointment, and I misspoke, slightly.
The ThreadPool thread that's executing your delegate obviously has to
have a reference to the delegate that it's executing, so clearly the
delegate can't be collected until it returns and the ThreadPool thread
is returned to the pool. (Presumably waiting threads have their
delegate-to-execute field cleared, precisely so that the delegates can
be collected.)
You should always call EndInvoke when you execute a delegate
asynchronously. The documentation is very firm about that, even if
it's not clear precisely why. Fwiw, I believe William Sullivan is
wrong about not calling EndInvoke causing a memory leak: the thread is
presumably returned to the pool as soon as the delegate returns, and
if you simply ignore the IAsyncResult that BeginInvoke returns, it
will ultimately be finalized and collected.
Take away messages:
1) Abandoning your MyWorker delegate will not cause premature
collection.
2) Not calling EndInvoke will not force the delegate to be immortal.
3) You should always call EndInvoke when you BeginInvoke a delegate.
If you don't want to bother, use ThreadPool.QueueUserWorkItem instead
of asynch execution.

Signature
.NET 2.0 for Delphi Programmers
www.midnightbeach.com/.net
What you need to know.