2010-11-24 6 views
12

Ich habe einen WCF-Dienst als solche implementiert:WCF-Dienst und IDisposable, räume ich verwaltete Objekte auf?

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext=false)] 
public sealed class SynchronizationService : ISynchronizationService, IDisposable 
{ 
    private MemoryStream objectStream; 

    ... 
} 

ISyncrhonizationService hat [Service (Session = SessionMode.Required)].

Wenn ein Client korrekt kommuniziert und schließlich eine Methode mit [IsTerminating = true] aufruft, kann ich die objectStream-Variable schön entsorgen. Wenn aus irgendeinem Grund die Kommunikation zwischen dem Dienst und dem Client unterbrochen wird, möchte ich die objectStream-Variable selbst von der Dienstseite bereinigen, weshalb ich die IDisposable-Schnittstelle implementieren möchte. Aber ein Blick auf der MSDN-Dokumentation (http://msdn.microsoft.com/en-us/library/system.idisposable.aspx) Ich bin ein bisschen skeptisch, weil gemäß der Dokumentation:

// Dispose(bool disposing) executes in two distinct scenarios. 
    // If disposing equals true, the method has been called directly 
    // or indirectly by a user's code. Managed and unmanaged resources 
    // can be disposed. 
    // If disposing equals false, the method has been called by the 
    // runtime from inside the finalizer and you should not reference 
    // other objects. Only unmanaged resources can be disposed. 

Weil es die Laufzeit, die die Methode Dispose ruft dann entsorgen = false. Daher sollte ich nicht auf objectStream zugreifen, da es ein verwaltetes Objekt ist. In diesem Fall sollte der SynccronizationService Finalizer, der von der Laufzeit bereitgestellt wird, von objectStream selbst bereinigen und ich muss IDisposable überhaupt nicht implementieren. Einige Forumsbeiträge deuten jedoch darauf hin, dass die SyncrhonizationService-Instanz stattdessen wiederverwendet und nicht entsorgt/finalisiert wird.

Also meine Fragen sind:

1) Was ist mit der SyncrhonizationService Instanz passiert eigentlich während Ausnahmen/Fehler/Timeouts/etc? Wird es zu einem späteren Zeitpunkt entsorgt oder einfach wiederverwendet?

2) Muss ich IDisposable implementieren und verfüge ich über verwaltete Objekte in der Dispose() - Methode?

3) Gibt es vielleicht eine bessere Alternative zu IDisposable, zum Beispiel so etwas wie ein channel_Faulted-Ereignis? Wenn ich über meine verwalteten Objekte in einem solchen Ereignis verfüge, wie und wo entferne ich den Event-Handler (ich könnte es im Event-Handler tun, aber was passiert, wenn ein anderer Typ von Ausnahme/Fehler auftritt)?

+4

Beachten Sie, dass IDisposable keine Dispose (bool) -Überlastung aufweist. Die zitierten Kommentare von MSDN dokumentieren das angegebene Codebeispiel und geben kein IDisposable-Verhalten an. Der Finalizer ruft Dispose nicht automatisch auf - Sie müssen ihn explizit codieren, wie im Codebeispiel gezeigt. Das Standardmuster hierfür ist das Hinzufügen einer Dispose-Überschreibung (bool), wie im Codebeispiel gezeigt. Im Fall Ihres Dienstes können Sie sicher sein, dass WCF Ihre Dispose() -Methode beim Beenden der Sitzung aufruft, sodass Sie keinen Finalizer benötigen (und nicht haben sollten). –

+0

Danke für das Aufräumen, jetzt macht alles Sinn :) – Marko

Antwort

18

Wenn Sie IDisposable implementieren, können Sie verwaltete Objekte in Ihrer Implementierung der Dispose() -Methode bereinigen.

Mit PerSession InstanceContextMode ruft die WCF-Laufzeit Dispose auf Ihrem SynchronizationService-Objekt auf, wenn die Sitzung beendet wird, unabhängig davon, ob der Client seinen Proxy geschlossen hat. aufgrund der Zeitüberschreitung der Sitzung durch Inaktivität (auf Client oder Server); oder durch den Kanalfehler.

Die Dienstinstanz wird nicht wiederverwendet: neue Sitzungen erhalten neue Instanzen Ihres SynchronisationsService.

Verwandte Themen