2011-02-12 2 views
0

je l'extrait suivant du code (par exemple) qui recherche un contact:Comment une méthode attend jusqu'à la fin d'un délégué anonyme?

public string Search() 
{ 
    string address = ""; 

    ContactManager manager = new ContactManager(); 

    // LookupComplete is just a plain event 
    manager.LookupComplete += delegate 
    { 
     address = manager.Address; 
    }; 

    manager.SearchFor("bob"); 
    return address; // Address always appears to be populated 
} 

Mise à jour:
Voici le ContactManager:

public class ContactManager 
{ 
    public string Address {get;set;} 
    public event LookupComplete; 

    public void SearchFor(string query) 
    { 
     SomeParser parser = new Parser(); 
     parser.TokenParsed += new EventHandler<TokenParseEventArgs>(tokenParsed); 
     parser.Parse(query);  
    } 

    private void tokenParsed(object sender,TokenParseEventArgs e) 
    { 
     if (e.Message == "EOF") 
     { 
      Address = e.Message.Address; 

      if (LookupComplete != null) 
       LookupComplete(this,EventArgs.Empty); 
     } 
    } 
} 

La méthode Search ne le fait pas retourner jusqu'à ce que cet événement soit déclenché (un comportement que je n'avais pas réalisé était standard pour les méthodes/délégués anonymes).

Je suis confus cependant comment le code généré pour le délégué anonyme signale la méthode Search quand il est terminé.

J'ai essayé de mettre un Sleep (5000) dans la propriété ContactManager.Address car je pensais que cela pouvait provenir du ContactManager qui revenait très rapidement, mais cela ne fait aucune différence.

Quelqu'un peut-il jeter de la lumière?

Répondre

5

Cela n'a rien à voir avec le fait que le délégué a été créé avec une méthode anonyme. C'est juste que manager.SearchFor est apparemment une méthode synchrone, qui ne retourne pas tant que la recherche n'est pas terminée. Cela le rend un peu étrange pour elle d'avoir un événement pour « recherche complète », il est vrai ... il semble que vous pouvez simplifier la méthode simplement:

public string Search() 
{ 
    ContactManager manager = new ContactManager(); 
    manager.SearchFor("bob"); 
    return manager.Address; 
} 

Maintenant, il est possible qu'il y ait également une option asynchrone disponible sur ContactManager - c'est difficile à dire sans en savoir plus sur la classe. Si est est une option asynchrone, vous devez considérer quel comportement vous voulez réellement ... êtes-vous heureux avec Search être synchrone, ou voulez-vous réellement qu'il se termine immédiatement et prendre une action lorsque la recherche est terminée?

+0

J'ai essayé de le simplifier avec des contacts, le 'ContactManager' est en fait ceci: http://hg.shrinkrays.net/spruce/src/0e9aee07563e/Spruce.Core/Search/SearchParser.cs. Il analyse les jetons dans une requête, mais ne fonctionne pas de manière synchrone autant que je le sache. –

+1

@Chris S: Je ne vois rien dans ce code suggérant que c'est asynchrone ... mais je ne vois pas le code pour LALRParser . Y a-t-il de la documentation qui vous suggère que c'est vraiment * as * asynchrone? –

+0

@Chris S Je n'ai trouvé aucun appel asynchrone là – gor

1

Cela dépend de l'implémentation de la classe ContactManager. Si elle est filetée et synchrone, elle ne peut pas revenir plus tôt, alors le travail est terminé.

Questions connexes