我正在将“同步”代码(即使用Windows事件等待直到其他线程完成某项操作)重构为“异步”代码(使用委托(delegate)来实现回调机制)。

在同步代码中,有时会有等待结束后需要使用的局部变量。当这样的代码异步时,这些局部变量将丢失(回调处理程序无法访问它们)。我可以将它们存储为类属性,但是感觉很浪费。

在C++中,我使用std::bind来解决此问题。我只需向回调处理程序添加所需数量的局部变量,然后在调用async方法时将其绑定(bind)。例如,假设异步方法回调接收到类型为CallbackParam的对象,并且调用方使用了两个类型为LocalALocalB的局部变量。

void AsyncClass::MethodWhichCallsAsyncMethod(){
    LocalA localVarA;
    LocalB localVarB;
    // OnAsyncMethodDone will need localVarA and localVarB, so we bind them
    AsyncMethod( std::bind( &AsyncClass::OnAsyncMethodDone, this, std::placeholders::_1, localVarA, localVarB ) );
}

void AsynClass::AsyncMethod( std::function<void(CallbackParam)> callback ){
    CallbackParam result;
    //Compute result...
    if( callback )
        callback( result );
}

void AsyncClass::OnAsyncMethodDone( CallbackParam p, LocalA a, LocalB b ){
   //Do whatever needs to be done
}

在C#和VB.NET中是否有与此等效的东西?使用委托(delegate)还是其他?

更新:出于完整性考虑,这是基于@lasseespeholt答案的示例的C#等效代码:
using System;

public class AsyncClass {

        public void MethodWhichCallsAsyncMethod() {
            var a = new LocalA();
            var b = new LocalB();
            //Anonymous callback handler (equivalent to AsyncClass::OnAsyncMethodDone)
            Action<CallbackParam> callback = result => {
                //Do what needs to be done; result, a and b can be accessed
            };
            AsyncMethod( callback );
        }

        private void AsyncMethod( Action<CallbackParam> callback ) {
            var result = new CallbackParam();
            //Compute result...
            if( callback != null )
                callback( result );
        }
}

最佳答案

更新:几乎肯定不应该使用它。在C#中使用async/await关键字

您可以利用如下所示的闭包:

void MethodWhichCallsAsyncMethod()
{
    int foo = 1;

    AsyncCallback callback = result =>
    {
        Console.WriteLine(foo); // Access to foo
    };

    AsyncMethod(callback);
}

void AsyncMethod(AsyncCallback callback)
{
    IAsyncResult result = null; // Compute result
    callback(result);
}

编译器会生成一个包含“foo”的类,因此您无需使用此方法保存任何内容,但是很干净。

09-05 22:57
查看更多