BeginInvoke内存泄漏?

时间:2013-01-02 15:54:57

标签: vb.net memory-leaks delegates

我正在对线程应用程序的一些奇怪行为进行故障排除,并偶然发现了一些使用BeginInvoke(Deligate)调用来启动异步任务的委托函数。我的研究表明,使用BeginInvoke而不与EndInvoke配对有机会导致内存泄漏,特别是在抛出异常的情况下,我认为这就是这种情况。

我给出的代码调用了一个委托,并且有一个回调函数,可以调用一个新的委托。我最好奇的是如何执行回调。是否有必要在最后一行发布新的委托?这个评论似乎对我没有任何意义。此外,回调的委托调用永远不会发出导致泄漏的EndInvoke调用,是否有更简单的方法来清除它然后创建回调方法?

另一个问题虽然不那么重要,但该函数的名称为Synchronized。从我看到的方法调用没有任何强制同步。 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 Sub

SynchronizedScheduleCompleted方法:

Private Sub SynchronizedScheduleCompleted()
    mAttemptingUpdate = False
    mOPCConnectionWorker.clearInvolked()
    SetInProgress(False)
End Sub

1 个答案:

答案 0 :(得分:2)

正确;不调用EndInvoke()会造成内存泄漏。

如果您只想“发射并忘记”异步操作而不处理其结果,则只需调用ThreadPool.QueueUserWorkItem(),它不会发生内存泄漏。

如果你关心结果,你应该使用 更容易使用的Task类。

没有任何理由致电Delegate.BeginInvoke()

而且,委托名称和方法中的单词Synchronized毫无意义。