2010-03-24 7 views
3

Je travaille sur une application Silverlight/WCF et bien sûr avoir de nombreux appels asynchrones à travers le programme Silverlight. Je me demandais comment est la meilleure façon de gérer la création des classes client et l'abonnement. Plus précisément, si je m'abonne à un événement dans une méthode, après son retour, est-ce qu'il tombe hors de la portée?C# Async appel garbage collection

internal MyClass 
{ 
    public void OnMyButtonClicked() 
    { 
     var wcfClient = new WcfClient(); 
     wcfClient.SomeMethodFinished += OnMethodCompleted; 
     wcfClient.SomeMethodAsync(); 
    } 

    private void OnMethodCompleted(object sender, EventArgs args) 
    { 
     //Do something with the result 

     //After this method does the subscription to the event 
     //fall out of scope for garbage collection? 
    } 
} 

Est-ce que je rencontrerai des problèmes si j'appelle à nouveau la fonction et que je crée un autre abonnement?

Merci d'avance à tous ceux qui répondent.

+0

En ce qui concerne le vissage GC avec vous, vous allez bien selon http://stackoverflow.com/questions/421547/does-the-garbage-collector-destroy-tunally-unreference-objects-during-async – Tanzelax

Répondre

2

Vous ne rencontrerez pas de problèmes. Il va générer une nouvelle instance WcfClient, et les deux appelleront votre callback OnMethodCompleted à la fin.

+0

Qu'est-ce que le mot "les deux" se réfèrent à? –

+0

@Daniel, "si j'appelle à nouveau la fonction et crée un autre abonnement" – Tanzelax

+0

Ah, gotcha ..... –

3

Vous ne devez pas laisser les proxys client WCF tomber simplement hors de portée comme ceci. Votre code fonctionnera mais il y aura aussi des fuites de ressources. Les clients WCF implémentent tous IDisposable, mais il s'agit d'un cas où vous ne pouvez pas utiliser using ou Dispose; le Service Proxy Helper peut être utilisé pour les opérations synchrones mais le code de nettoyage qui s'y trouve montre comment disposer du client en toute sécurité dans n'importe quel contexte. Lorsque vous exécutez async opérations de ce type, quelque chose doit gérer la durée de vie de ce client de la même manière. Normalement, quelle que soit la classe "propriétaire" du client WCF devrait implémenter IDisposable lui-même, garder une référence à ce client dans un domaine privé quelque part, et invoquer Close/Abort sur le client dans sa méthode de disposition.

Généralement, quelle que soit la classe qui implémente réellement la méthode de rappel asynchrone va être le propriétaire, et donc cette classe devrait gérer la durée de vie; par conséquent, si vous avez réellement besoin d'un client «à la demande», il peut également être judicieux d'effectuer le nettoyage une fois le rappel terminé.

Les clients WCF ne sont pas non plus très faciles à créer, vous devriez donc essayer de les garder aussi longtemps que possible et ne pas les créer de façon ad-hoc; Considérez-les comme des dépendances à l'échelle de l'application.

Si vous ne faites que suivre l'instance du client, vous n'avez pas besoin de continuer à vous abonner à ses événements; la question disparaît effectivement.

+0

+1, comme cela semble être le bon conseil, mais va-t-il vraiment fuir les ressources à long terme? Ou sera-t-il finalisé à un moment donné? –

+0

Merci pour votre réponse. Je pensais que le moyen approuvé serait de le créer au niveau de la classe et cela le confirme à peu près. Il m'a semblé que je faisais quelque chose de mal en m'abonnant et en me désabonnant à des événements que l'utilisateur pourrait ou non utiliser. – Troy

+0

@Daniel Earwicker: Tout finira par être finalisé, bien sûr - de même qu'un 'SqlConnection' ou' Bitmap' - la question est * quand *. Si vous gardez des ressources non managées (sockets, mutex, poignées, etc.), vous pouvez finir par mourir de faim si vous ne les libérez pas, car le GC ne se lancera que lorsqu'il aura besoin de * memory *. – Aaronaught