Vb.net .NET结束调用/发布操作已完成

Vb.net .NET结束调用/发布操作已完成,vb.net,multithreading,asynchronous,Vb.net,Multithreading,Asynchronous,我的问题涉及VB.NET中的异步操作 鉴于以下情况: Delegate WorkerDelegate(Byval asyncOp As AsyncOperation) Public Sub StartWork() Dim worker as new WorkerDelegate(AddressOf DoWork) Dim asyncOp as AsyncOperation = AsyncOperationManager.CreateOperation(New O

我的问题涉及VB.NET中的异步操作

鉴于以下情况:

Delegate WorkerDelegate(Byval asyncOp As AsyncOperation)

Public Sub StartWork()        
    Dim worker as new WorkerDelegate(AddressOf DoWork)
    Dim asyncOp as AsyncOperation = AsyncOperationManager.CreateOperation(New Object)

    // begin work on different thread
    worker.BeginInvoke(asyncOp, Nothing, Nothing)
End Sub

Private Sub DoWork(Byval asyncOp as AsyncOperation)
    // do stuff

    // work finished, post
    asyncOp.PostOperationCompleted(AddressOf OnDownloadFinished, Nothing)                
End Sub

Private Sub OnDownloadFinished()
    // Back on the main thread now

End Sub
我读过的大多数参考资料都说,如果在委托上使用BeginInvoke,则必须调用EndInvoke。在上面的示例中,我使用PostOperationCompleted方法切换回线程并报告操作已完成


在OnDownloadFinished方法中调用worker.BeginInvoke并添加worker.EndInvoke时,是否仍需要获得IAsyncResult?

调用EndInvoke是最佳做法,因为这是清理AsyncResult分配的资源的时候

但是,如果不访问WaitHandle属性,那么异步委托使用的异步结果不会使用任何资源,因此不调用EndInvoke可能没有影响

在您的场景中,您应该考虑使用.

,在您的<>代码> OnDead Load完成方法看起来是这样的:

// This method is invoked via the AsyncOperation object,
// so it is guaranteed to be executed on the correct thread.
private void CalculateCompleted(object operationState)
{
    CalculatePrimeCompletedEventArgs e =
        operationState as CalculatePrimeCompletedEventArgs;

    OnCalculatePrimeCompleted(e);
}

它不调用
EndInvoke()
。因此,可以安全地假设在
PostOperationCompleted
处理程序中不调用
EndInvoke()
是可以的。

+1表示QueueUserWorkItem。在可能的时候使用它,在必须的时候使用原始调用和线程。同意QueueUserWorkItem,但是关于EndInvoke清理资源的内容是毫无意义的。如果需要,可以调用EndInvoke从委托中检索返回值,但这不是必需的。EndInvoke将处理IAsyncResult.WaitHandle(如果已访问)。访问WaitHandle而不调用EndInvoke将对垃圾收集器中的finalize队列施加压力。如果正在完成的“工作”是下载一个可能需要一段时间才能完成的文件,您还会使用QueueUserWorkItem吗?线程池线程的一般规则是,它们需要快速完成,对吗?Delegate.BeginInvoke也在线程池中对委托进行排队。也许你应该在标题中创建一个新的线程,我同意你的逻辑(是的,这个链接就是我获取模式的地方)。然而,大量MSDN示例都有用户指出的错误,不知道不调用EndInvoke是否是MS的疏忽