我正在对一个线程化应用程序的一些奇怪行为进行故障排除,并且偶然发现了一些使用BeginInvoke(Deligate)调用来启动异步任务的委托函数。我的研究表明,在不与EndInvoke配对的情况下使用BeginInvoke有可能导致内存泄漏,特别是在抛出异常的情况下,我认为这里就是这种情况。
我得到的代码调用一个委托,并且有一个回调函数调用新的委托本身。我最好奇的是回调是如何执行的。是否有必要在最后一行上发布一个新的委托?这句话对我来说似乎没什么意义。另外,回调的委托调用永远不会发出导致泄漏的EndInvoke调用,有没有比创建回调方法更简单的方法来清理这个问题呢?
另一个问题是函数的名称,虽然不是很重要。根据我所看到的,在方法调用中没有强制同步。VB.NET是自动设置同步的,还是上一位开发人员只是在说些花哨的话?
初始调用:
mDelegateUpdate3.BeginInvoke(mCallbackUpdate3, mDelegateUpdate3)回调方法:
Public Sub OnUpdateSchedule3Complete(ByVal ar As IAsyncResult)
' Clean up original thread
Dim del As OPCConnectionWorkerDelegate
del = CType(ar.AsyncState, OPCConnectionWorkerDelegate)
del.EndInvoke(ar)
'We are on the wrong thread so we need to switch back to the UI thread
Dim ar1 As IAsyncResult
ar1 = Me.BeginInvoke(New SynchronizedScheduleCompletedDelegate(AddressOf Me.SynchronizedScheduleCompleted))
End SubSynchronizedScheduleCompleted方法:
Private Sub SynchronizedScheduleCompleted()
mAttemptingUpdate = False
mOPCConnectionWorker.clearInvolked()
SetInProgress(False)
End Sub发布于 2013-01-02 23:57:18
正确;不调用EndInvoke()会造成内存泄漏。
如果您只想“触发并忘记”一个异步操作,而不是处理它的结果,那么您应该简单地调用ThreadPool.QueueUserWorkItem(),它没有内存泄漏的可能性。
如果您确实关心结果,那么应该使用Task类,它更易于使用。
再也没有理由调用Delegate.BeginInvoke()了。
而且,委托和方法名称中的单词Synchronized是没有意义的。
https://stackoverflow.com/questions/14125008
复制相似问题