为啥即使服务仍然引用它,也会在 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?的主要内容,如果未能解决你的问题,请参考以下文章
即使未加载 codeigniter 会话库,也会在数据库中创建新的会话条目。为啥?
为啥即使我没有将 vuex 状态绑定到任何 html 输入元素,我的 vuex 状态也会在更改组件级别状态时发生变化?
即使存在 try/catch 块,应用程序也会在空对象引用上出现“布尔 android.content.Intent.migrateExtraStreamToClipData()”