2012-07-09 13 views
9

He definido la siguiente DataContract que implementa IDisposable:¿Por qué se usa Disposición en DataContract aunque el servicio todavía se refiere a ella?

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

Y llamar al siguiente método de servicio que pasa una instancia del contrato de datos anterior:

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

En la implementación de BeginUpload, simplemente guardar metadata en un diccionario como:

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

Mi pregunta es, inmediatamente después de regresar de este método, ¿por qué se llama a Dispose() aunque he guardado la instancia en el diccionario _Dict?

He comprobado que Dispose() método se llama en la misma ejemplo que he guardado en mi diccionario, como se hace _Disposedtrue para la salvados objeto, es decir _Dict[sessionId]._Disposed convierte true!

El comportamiento en servicio de mi servicio se establece como:

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

¿Estás fisura que botar (..) se llama en la ** misma ** instancia que usted creó? Quiero decir, * puede ser * se creó otra instancia de la clase y se invocó a Dispose (..) en * that * one. Comprueba * hashcode * de la instancia que obtienes (...) en ... – Tigran

+0

@Tigran: Sí ... – Nawaz

+0

@Tigran: Actualicé mi pregunta con: * "He verificado que se llama al método Dispose() en el la misma instancia que he guardado en mi diccionario, ya que _Disposed se convierte en verdadero para el objeto guardado. "* – Nawaz

Respuesta

14

Está dispuesta porque ese objeto "pertenece" a WCF - se crea la instancia del objeto de la nada, a pasar como un parámetro a su método. Y es lo suficientemente amable para observar que este objeto implementa IDisposable, por lo que se deshace de él una vez que se completa el método.

Si desea que una instancia de este objeto se cuelgue después de que se complete su método, entonces necesita crear una instancia usted mismo, copiando los detalles relevantes de una instancia a la otra.

qué Dispose() se llama pesar de que he salvado la instancia en el diccionario _Dict

Debido a que el patrón de Disposetiene nada que ver con referencias y recolección de basura. Lo único que importa es que, siempre que se pasen referencias a un objeto desechable entre múltiples métodos/actores/agentes, exista un acuerdo sobre "quién" es responsable de llamar al Dispose y cuándo. En este caso, el "quién" es la infraestructura de WCF.


corrección - puede alterar este comportamiento agregando el atributo OperationBehavior a su método, y el establecimiento de AutoDisposeParameters false:

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

+1. Tiene sentido. :-) – Nawaz

Cuestiones relacionadas