2012-07-09 13 views
9

I zostały zdefiniowane następujące DataContract który implementuje IDisposable:Dlaczego Dispose jest wywoływana w DataContract, mimo że usługa wciąż go odsyła?

[DataContract] 
public class RegularFileMetadata : FileMetadataBase, IDisposable 
{ 
    bool _Disposed = false; //note this! 

    //... 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!_Disposed) 
     { 
      //... 
      _Disposed = true; //note this too! 
     } 
    } 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
} 

i wzywam następujące metody usługi przechodzącego wystąpienie powyższej umowy danych:

[OperationContract] 
[ServiceKnownType(typeof(RegularFileMetadata))] 
Guid BeginUpload(FileMetadataBase metadata); 

W realizacji BeginUpload, po prostu zapisz metadanych w słowniku jako:

Dictionary<Guid, RegularFileMetadata> _Dict; 

public Guid BeginUpload(FileMetadataBase fileMetadata) 
{ 
    //... 
    var metadata = fileMetadata as RegularFileMetadata; 
    Guid sessionId = Guid.NewGuid(); 
    _Dict.Add(sessionId, metadata); //metadata SAVED! 
    return sessionId ; 
} 

Moje pytanie brzmi, zaraz po powrocie z tej metody, dlaczego jest wywoływana Dispose(), mimo że zapisałem wystąpienie w słowniku _Dict?

I sprawdzeniu, że Dispose() metoda jest wywoływana na samym instancji, które mam zapisane w moim słowniku, jak _Disposed staje true dla zapisane obiektu, tj _Dict[sessionId]._Disposed staje true!

Zachowanie serwis mojego usługi jest ustawiony jako:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
+0

Czy jesteś ssure że Dispose (..) jest wywoływana na ** ta sama ** utworzona przez ciebie instancja? Mam na myśli, * może być * utworzono kolejną instancję klasy i Dispose (...) została wywołana * tą * jedną. Sprawdź * hashcode * instancji, którą otrzymasz Dispose (..) na ... – Tigran

+0

@ Tigran: Tak ... – Nawaz

+0

@ Tigran: Zaktualizowałem moje pytanie: * "Sprawdziłem, że metoda Dispose() jest wywoływana to samo wystąpienie, które zapisałem w słowniku, ponieważ _Disposed staje się prawdziwe dla zapisanego obiektu. "* – Nawaz

Odpowiedz

14

To jest umieszczona ponieważ obiekt „należy” do WCF - stworzył instancję obiektu z powietrza, aby przekazać jako parametr do listy metoda. Na tyle uprzejmie można zauważyć, że obiekt ten implementuje IDisposable, więc go pozbywa się po zakończeniu metody.

Jeśli chcesz, aby instancja tego obiektu była zawieszana po zakończeniu metody, musisz utworzyć taką instancję samodzielnie, kopiując odpowiednie szczegóły z jednej instancji do drugiej.

dlaczego Dispose() nazywa chociaż mam zapisane instancji w słowniku _Dict

Ponieważ wzór Dispose ma nic do czynienia z referencjami i zbierania śmieci. Liczy się tylko to, że w przypadku przekazywania referencji do obiektu jednorazowego użytku między wieloma metodami/aktorami/agentami istnieje porozumienie co do "kto" jest odpowiedzialny za wywołanie Dispose i kiedy. W tym przypadku "who" jest infrastrukturą WCF.


Correction - można zmienić to zachowanie dodając atrybut OperationBehavior do metody i ustawienie AutoDisposeParameters false:

[OperationBehavior(AutoDisposeParameters=false)] 
public Guid BeginUpload(FileMetadataBase fileMetadata) 
{ 
    //... 
    var metadata = 
+0

+1. Ma sens. :-) – Nawaz