2

スレッド化されたアプリケーションの奇妙な動作のトラブルシューティングを行っており、BeginInvoke(Deligate)呼び出しを使用して非同期タスクを開始するいくつかのデリゲート関数に遭遇しました。私の調査によると、BeginInvokeとペアリングせずに使用EndInvokeすると、特に例外がスローされた場合にメモリリークが発生する可能性があります。これは、ここに当てはまると思います。

私が与えられたコードはデリゲートを呼び出し、新しいデリゲート自体を呼び出すコールバック関数を持っています。私が最も興味を持っているのは、コールバックがどのように実行されるかです。最後の行に新しい代理人を発行する必要がありますか?そのコメントは私には意味をなさないようです。また、コールバックのデリゲート呼び出しEndInvokeがリークの原因となる呼び出しを発行することはありません。これをクリーンアップしてからコールバックメソッドを作成するためのより簡単な方法はありますか?

それほど重要ではありませんが、もう1つの懸念事項は、同期化された関数の名前です。私が見たところ、メソッド呼び出しに同期を強制するものは何もありません。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
4

1 に答える 1

2

正しい; 呼び出さないとEndInvoke()、メモリリークが発生します。

非同期操作を「ファイアアンドフォーゲット」し、その結果を処理したくない場合は、単に呼び出す必要がありますThreadPool.QueueUserWorkItem()。これは、メモリリークの可能性がありません。

結果を気にする場合は、はるかに使いやすいTaskクラスを使用する必要があります。

を呼び出す理由はもうありませんDelegate.BeginInvoke()

そして、Synchronized代表者の名前と方法の言葉は無意味です。

于 2013-01-02T15:57:18.233 に答える