10

我已经定义了以下DataContract实现IDisposable

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

我调用以下服务方法传递上述数据协定的实例:

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

在 的实现中BeginUpload,我只是将元数据保存在字典中:

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

我的问题是,从这个方法返回后,为什么Dispose()即使我已经将实例保存在字典中,也会被调用_Dict

我已经验证了该Dispose()方法是在我保存在字典中的同一个实例上调用的,就像保存对象一样,即_Disposed变成!true_Dict[sessionId]._Disposedtrue

我的服务的服务行为设置为:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
4

1 回答 1

15

它被处置是因为该对象“属于”WCF - 它凭空创建了对象实例,作为参数传递给您的方法。而且,观察到这个对象实现IDisposable了是很友好的,所以一旦你的方法完成它就会处理它。

如果您希望该对象的实例在您的方法完成后挂起,那么您需要自己创建这样一个实例,将相关细节从一个实例复制到另一个实例。

为什么Dispose()即使我已将实例保存在字典中也会调用_Dict

因为Dispose模式与引用和垃圾收集无关。重要的是,每当对一次性对象的引用在多个方法/参与者/代理之间传递时,就“谁”负责调用Dispose以及何时调用达成一致。在这种情况下,“谁”是 WCF 基础结构。


OperationBehavior更正 - 您可以通过将属性添加到您的方法并设置AutoDisposeParameters为 false来更改此行为:

[OperationBehavior(AutoDisposeParameters=false)]
public Guid BeginUpload(FileMetadataBase fileMetadata)
{
    //...
    var metadata = 
于 2012-07-09T08:07:43.103 回答