为啥即使服务仍然引用它,也会在 DataContract 上调用 Dispose?

Posted

技术标签:

【中文标题】为啥即使服务仍然引用它,也会在 DataContract 上调用 Dispose?【英文标题】:Why Dispose is being called on DataContract even though the service still refers to it?为什么即使服务仍然引用它,也会在 DataContract 上调用 Dispose? 【发布时间】:2012-07-08 13:31:05 【问题描述】:

我定义了以下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 ;

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

我已经验证 Dispose() 方法在我保存在我的字典中的 same 实例上被调用,因为 _Disposed 变为 true 对于 saved对象,即_Dict[sessionId]._Disposed变成true

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

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

【问题讨论】:

您确定在您创建的 same 实例上调用了 Dispose(..) 吗?我的意思是,可能创建了该类的另一个实例,并且在 那个 上调用了 Dispose(..)。检查你得到 Dispose(..) 的实例的 hashcode... @Tigran:我更新了我的问题:“我已经验证了 Dispose() 方法是在我保存在字典中的同一个实例上调用的,因为 _Disposed 对于保存的对象。” 【参考方案1】:

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

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

为什么Dispose() 被调用,即使我已经将实例保存在字典_Dict

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


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

[OperationBehavior(AutoDisposeParameters=false)]
public Guid BeginUpload(FileMetadataBase fileMetadata)

    //...
    var metadata = 

【讨论】:

以上是关于为啥即使服务仍然引用它,也会在 DataContract 上调用 Dispose?的主要内容,如果未能解决你的问题,请参考以下文章

即使我的应用程序关闭,也会在后台运行 dart 代码

即使未加载 codeigniter 会话库,也会在数据库中创建新的会话条目。为啥?

为啥即使我没有将 vuex 状态绑定到任何 html 输入元素,我的 vuex 状态也会在更改组件级别状态时发生变化?

即使存在 try/catch 块,应用程序也会在空对象引用上出现“布尔 android.content.Intent.migrateExtraStreamToClipData()”

为啥while循环有时会在满足退出条件之前退出?

为啥即使文件存在于服务器上,jQuery ajax 也会返回 404 Not found 错误?