34 votes

Un objet .Net/CMD devrait-il appeler Dispose() sur lui-même ?

Ci-dessous est un exemple de code écrit par un collègue. Cela semble évidemment mauvais pour moi, mais je voulais vérifier. Si un appel de l'objet de sa propre Dispose() méthode à partir de l'un de ses propres méthodes? Il me semble que seul le propriétaire/créateur de l'objet devrait appeler Dispose() quand il est fait avec l'objet et non l'objet lui-même.

C'est un .web asmx méthode qui appelle Dispose() sur lui-même quand il est fait. (Le fait que c'est une méthode web est probablement l'accessoire à la question en général.) Dans notre base de code nous avons parfois instancier web les classes de service au sein des méthodes autres que les services web et ensuite appeler des méthodes sur eux. Si mon code n'a qu'à appeler cette méthode, l'objet est grillé quand le retour de la méthode et je ne peux pas vraiment utiliser l'objet de plus.

[WebMethod]
public string MyWebMethod()
{
    try
    {
        return doSomething();
    }
    catch(Exception exception)
    {
        return string.Empty;
    }
    finally
    {
        Dispose(true);
    }
}

Mise à JOUR: Trouvé quelques liens qui sont liés:

Ai-je besoin de disposer d'un service web de référence dans ASP.NET?

Disposer une classe Proxy de Service Web?

34voto

EvgK Points 1299

C'est sûr que ce n'est pas un bon prartice. L'appelant doit décider quand il a fini d'utiliser l'objet IDisposable, et non un objet lui-même.

4voto

Fredou Points 9553

si jamais je vois que dans un de mes projets, je voudrais demander pourquoi et je suis 99,9999% sûr que je voudrais le supprimer de toute façon

pour moi c'est une sorte de drapeau rouge / odeurs de code

1voto

Jeffrey L Whitledge Points 27574

Il n'y a pas de restrictions techniques sur ce qu'est une méthode dispose est autorisé à le faire. La seule chose de spécial, c'est que d'en Disposer est appelé dans certaines constructions (foreach, using). À cause de cela, Jetez pourrait raisonnablement être utilisé pour marquer un objet qui n'est plus utilisable, surtout si l'appel est idempotent.

Je ne voudrais pas l'utiliser à cette fin cependant, en raison de la a accepté de la sémantique de la Jeter. Si je voulais marquer un objet qui n'est plus utilisable à partir de l'intérieur de la classe elle-même, alors je voudrais créer un MarkUnuseable() méthode qui pourrait être appelée par l'élimination ou à tout autre endroit.

En limitant les appels à Jeter à la vulgate de modèles, vous achetez la capacité d'apporter des changements aux méthodes dispose dans l'ensemble de vos classes avec confiance que vous n'aurez pas de façon inattendue casser le code qui s'écarte du modèle commun.

0voto

supercat Points 25534

Tout en un .Net objet ne serait pas normalement appel Jeter sur elle-même, il ya des moments où le code s'exécute à l'intérieur d'un objet peut être la dernière chose qui s'attend à l'utiliser. Comme exemple simple, si une méthode dispose peut gérer le nettoyage d'une partie-objet construit, il peut être utile d'avoir un constructeur codé quelque chose comme ce qui suit:

Sub New()
 Dim OK as Boolean = False
Essayez
 ... faire des Trucs
 OK = True
Enfin
 Si Pas OK, Puis sur Moi.Disposer
 End Try
End Sub

Si le constructeur va lancer une exception sans retour, puis partiellement objet construit, qui est prévue pour la cessation d'exploitation, sera la seule chose qui n'aura jamais l'information et l'élan nécessaire pour faire le nettoyage nécessaire. Si elle ne prend pas soin de s'assurer en temps opportun d'une Cession, rien d'autre.

En ce qui concerne votre morceau de code, le motif est un peu inhabituel, mais il ressemble un peu à la manière d'un socket peut se passer d'un thread à l'autre. Il y a un appel qui renvoie un tableau d'octets et annule une Prise de courant; ce tableau d'octets peut être utilisé dans un autre thread pour créer une nouvelle instance Socket qui prend le pas sur le volet communications établies par l'autre Socket. Notez que les données concernant le socket ouvert est effectivement une ressource non managée, mais il ne peut pas très bien enveloppé dans un objet avec un finaliseur parce que c'est souvent va être remis à quelque chose que le garbage collector ne pouvez pas voir.

0voto

Guilherme J Santos Points 1253

Il suffit de le retirer, mais prenez soin de le disposer dans tous les objets qui l'appellent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X