2009-12-29 6 views
6

Ich arbeite an einem .NET-Projekt, das mit einigen benutzerdefinierten Klassen interagieren muss - bezeichnet als "Jobs". Alle Jobklassen müssen eine spezifische Schnittstelle IJob in der Reihenfolge implementieren, in der die Bibliothek sie verwendet. Manchmal enthält eine Jobklasse möglicherweise nicht verwaltete Ressourcen, die explizit entsorgt werden müssen.Wie soll ich die Entsorgung von möglicherweise wegwerfbaren Objekten sicherstellen?

Wie soll ich sicherstellen, dass alle Arbeitsplätze nach Gebrauch entsorgt werden, wenn ich nicht im Voraus wissen, ob der Job explizit Entsorgung muss? Ich habe ein paar Ideen selbst, aber möchten Sie Ihre Kommentare/Anregungen hören:

  1. IJob : IDisposable Stellen und zwingt alle Jobs eine Dispose() Methode zu implementieren. Dies ermöglicht es mir, mit Arbeitsplätzen in using Blöcken zu arbeiten, aber da die meisten Arbeitsplätze sind nicht explizite Verfügung benötigen erwartet, könnte dies für den Client-Entwickler unnötige Verwirrung.

  2. alle Arbeit tun Arbeitsplätze in try-finally Blöcken beteiligt und finally verwenden, um sicherzustellen, dass Dispose(), wenn der Job IDisposable implementiert genannt wird. Dies erleichtert es den Clients, eine neue Job-Klasse zu implementieren - indem sie keine leere Dispose()-Methode implementieren muss -, sondern verbirgt auch die Tatsache, dass die Bibliothek verfügbare Jobs kennt und sich um sie kümmert.

Danach Schreiben auf, neige ich dazu, in Richtung Lösung # 1 zu lehnen, aber ich denke immer noch, es wäre schön, alternative Lösungen zu sehen, und zusätzliche Vor/Nachteile zu den beiden habe ich bereits im Kopf.

Antwort

8

einverstanden Es gibt einen Präzedenzfall: Die Stream-Basisklasse ist IDisposable nad daher alle Streams Nachkommen . Aber MemoryStream benötigt keine Disposition.
Aber zielen Sie nicht auf Versuch/schließlich ist der using() { } Block eine bequemere Kurzschrift.

So Ihre Wahl ist: Haben Sie alle Jobs wollen einige sein IDisposable oder gerade?

Die erste Option einen kleinen Overhead verursacht, macht die zweite leichter entsorgen zu vergessen (mit), wenn es notwendig ist.

+0

Guter Punkt. Die meisten Streams müssen jedoch entsorgt werden, und ich erwarte, dass nur eine Minderheit von Arbeitsplätzen diese benötigt. –

+0

Es kommt mir vor, dass 'System.Web.IHttpModule' auch seine Implementierer benötigt, um eine' Dispose() 'Methode zur Verfügung zu stellen, obwohl nur ein paar Module (IMHO) es brauchen. Ich denke, das bietet zusätzliche Priorität für # 1. –

+1

+1, ich denke außerdem, es macht Sinn, eine standardisierte Methode für einen Job zur Verfügung zu stellen, um aufzuräumen, was es verwendet. Durch den Einsatz von IDisposable profitieren Sie von der Framework-Unterstützung, und die Endnutzer profitieren davon, dass sie zumindest darüber nachdenken müssen, wo sie den richtigen Bereinigungscode platzieren können. – user7116

2

Ich würde mit # 2 gehen und dokumentieren, dass jedes Einwegobjekt entsorgt wird. Grundsätzlich, wenn Sie ein Objekt besitzen, sind Sie verpflichtet, Objekte zu entsorgen, die IDisposable implementieren.

Wenn Sie lesen Effective C#/More Effective C#, Bill Wagner den gleichen Rat geben (was ich mit offensichtlich ;-)

+0

Die OP bereits im Besitz Objekte in beiden Optionen wird entsorgen, so sehe ich nicht, wie das ist ein Argument für die Option # 2. –

3

Ich denke auf diese Weise. Ich würde lieber einen Entwickler implementieren eine leere Dispose Methode als vergessen, eine notwendige Dispose Methode zu implementieren.

5

# 2 ist, wie das foreach Konstrukt funktioniert. So funktioniert auch die Containerentsorgung von Autofac.

Der semantische Unterschied ist, ob man sagen, dass ein Job selbst Einweg ist, oder ob eine Implementierung könnte Einweg sein.

Es ist aus Ihrem Beispiel klar, dass die ehemaligen ist nicht wahr, dass die Arbeitsplätze sind nicht von Natur aus Einweg.Daher empfehle ich, # 2, aber mit einer Erweiterung Methode zur Zentralisierung der try/finally:

public static void Execute(this IJob job) 
{ 
    try 
    { 
     job.Run(); 
    } 
    finally 
    { 
     var disposableJob = job as IDisposable; 

     if(disposableJob != null) 
     { 
      disposableJob.Dispose(); 
     } 
    } 
} 
+0

+1, Ich mag Ihre Argumentation über Semantik, aber ich denke, ich werde mit der ersten Lösung gehen, aus den Gründen in den anderen Antworten und der Frage selbst erwähnt. –

Verwandte Themen