2013-04-05 97 views
4

我正在重构“同步”代码(即,使用Windows事件等待某个其他线程完成某件事情)到“异步”代码(使用委托来实现回调机制)。std :: bind在C#或VB.NET中的等效代码

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

在C++中,我使用std::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中是否存在某种等价的东西?使用委托或其他东西?

UPDATE:为了完整起见,这里是C#相当于基于@ lasseespeholt的回答我的例子中的:

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); 
     } 
} 

回答

3

UPDATE:这应该几乎肯定不能使用。使用异步/等待在C#中的关键字

你可以利用像下面的关闭:

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); 
} 

编译器生成包含“富”这样你就不会保存使用这种方法的任何一类,但它很干净。

+0

看起来不错;我不愿意将状态添加到我的类中,但是如果编译器执行它,我不介意:P这是否也可以在VB.NET中完成? (我们正在讨论.NET 4.0) – 2013-04-05 19:29:35

+1

@dario_ramos我自己不使用VB.Net,但是。 C#和VB.Net共享大部分功能。这个页面应该可以帮助你在VB.Net中使用lambdas:http://msdn.microsoft.com/en-us/library/bb531253.aspx – 2013-04-05 19:30:46