2012-07-09 24 views
9

Ho definito il seguente DataContract che implementa IDisposable:Perché Dispose viene chiamato su DataContract anche se il servizio si riferisce ancora ad esso?

[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); 
    } 
} 

E io chiamare il seguente metodo di servizio passando un'istanza del contratto dei dati di cui sopra:

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

Per l'attuazione del BeginUpload, ho semplicemente salva metadati in un dizionario come:

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 ; 
} 

La mia domanda è, immediatamente dopo il ritorno da questo metodo, perché Dispose() viene chiamato anche se ho salvato l'istanza nel dizionario _Dict?

Ho verificato che Dispose() metodo viene chiamato sulla stesso esempio che ho salvato nel mio dizionario, come _Disposed diventa true per la salvati oggetto, cioè _Dict[sessionId]._Disposed diventa true!

Il comportamento di servizio del mio servizio è impostato come:

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

Sei ssure che Dispose (..) viene chiamato sul ** stessa istanza ** che hai creato? Voglio dire, * potrebbe essere * è stata creata un'altra istanza della classe e Dispose (..) è stato chiamato * that * one. Controlla * codice hash * dell'istanza che ottieni Dispose (..) su ... – Tigran

+0

@Tigran: Sì ... – Nawaz

+0

@Tigran: Ho aggiornato la mia domanda con: * "Ho verificato che il metodo Dispose() è chiamato sul stessa istanza che ho salvato nel mio dizionario, poiché _Disposed diventa true per l'oggetto salvato. "* – Nawaz

risposta

14

E 'in via di dismissione in quanto tale oggetto "appartiene" a WCF - ha creato l'istanza dell'oggetto dal nulla, di passare come parametro per il vostro metodo. E, è abbastanza gentile da osservare che questo oggetto implementa IDisposable, quindi lo smaltisce una volta completato il tuo metodo.

Se si desidera che un'istanza di questo oggetto si blocchi dopo il completamento del metodo, è necessario creare tale istanza da soli, copiando i dettagli rilevanti da un'istanza all'altra.

perché Dispose() si chiama anche se ho salvato l'istanza nel dizionario _Dict

Poiché il modello Dispose ha nulla a che fare con riferimenti e raccolta dei rifiuti. Tutto ciò che conta è che, ogni volta che i riferimenti a un oggetto usa e getta vengono passati tra più metodi/attori/agenti, c'è un accordo su "chi" è responsabile per chiamare Dispose e quando. In questo caso, "who" è l'infrastruttura WCF.


Correzione - è possibile modificare questo comportamento aggiungendo l'attributo OperationBehavior al metodo, e l'impostazione AutoDisposeParameters su false:

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

+1. Ha senso. :-) – Nawaz

Problemi correlati