gpt4 book ai didi

c# - 为什么在 DataContract 上调用 Dispose,即使服务仍然引用它?

转载 作者:可可西里 更新时间:2023-11-01 09:03:16 25 4
gpt4 key购买 nike

我定义了以下 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 的实现中,我只是将 metadata 保存在字典中:

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 对于 saved 对象,即 _Dict[sessionId]._Disposed 变为 true!

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

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

最佳答案

它被处置是因为该对象“属于”WCF - 它凭空创建了对象实例,作为参数传递给您的方法。而且,很高兴看到该对象实现了 IDisposable,因此它会在您的方法完成后处理它。

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

why Dispose() is called even though I've saved the instance in the dictionary _Dict

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


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

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

关于c# - 为什么在 DataContract 上调用 Dispose,即使服务仍然引用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11390168/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com