2013-04-05 4 views
4

Je suis en train de refactoriser le code "synchrone" (c'est-à-dire utilise les événements Windows pour attendre qu'un autre thread finisse de faire quelque chose) en code "asynchrone" (en utilisant des délégués pour implémenter un mécanisme de rappel).std :: bind équivalent en C# ou VB.NET

Dans le code de synchronisation, j'ai parfois des variables locales que je dois utiliser une fois l'attente terminée. Quand un tel code est asynchrone, ces variables locales sont perdues (le gestionnaire de rappel ne peut pas y accéder). Je peux les stocker en tant qu'attributs de classe, mais cela me semble inutile. En C++, j'utilise std::bind pour contourner le problème. J'ajoute juste autant de paramètres que les variables locales nécessaires au gestionnaire de callback, et les lie quand j'appelle la méthode asynchrone. Par exemple, disons que le rappel de la méthode async reçoit un objet de type CallbackParam et que l'appelant utilise deux variables locales de type LocalA et LocalB. Y a-t-il une sorte d'équivalent en C# et en VB.NET? En utilisant des délégués ou autre chose?

MISE À JOUR: Pour être complet bien, voici le C# équivalent de mon exemple basé sur la réponse de @ 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); 
     } 
} 

Répondre

3

MISE À JOUR: Cela devrait certainement pas être utilisé. Utilisez le async/attendre les mots clés C#

Vous pouvez exploiter des fermetures comme les suivantes:

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

Le compilateur génère une classe qui contient « foo » de sorte que vous n'enregistrez rien avec cette approche, mais c'est propre.

+0

Ça a l'air bien; J'étais réticent à ajouter un état à ma classe, mais si le compilateur le fait, cela ne me dérange pas: P Cela peut-il être fait aussi dans VB.NET? (Nous parlons .NET 4.0) –

+1

@dario_ramos Je n'utilise pas moi-même VB.Net mais oui. C# et VB.Net partagent la plupart des fonctionnalités. Cette page devrait vous aider à utiliser lambdas dans VB.Net: http://msdn.microsoft.com/en-us/library/bb531253.aspx –