Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在IDisposable类的反序列化过程中,是否有方法确保在异常时调用Dispose()?_C#_Exception_Xml Serialization_Idisposable - Fatal编程技术网

C# 在IDisposable类的反序列化过程中,是否有方法确保在异常时调用Dispose()?

C# 在IDisposable类的反序列化过程中,是否有方法确保在异常时调用Dispose()?,c#,exception,xml-serialization,idisposable,C#,Exception,Xml Serialization,Idisposable,在c#中,我反序列化了一个类型为的对象,该对象使用以下语句实现IDisposable(仅供说明) 好的,序列化程序尝试使用默认的构造函数构造对象,并随后分配所有公共属性和字段。如果出现任何异常,我将无法获得构造的对象 所以,我的问题是,是否有任何方法可以确保自动释放尚未分配的资源。我知道Dispose(bool disposing)-“模式”实现了一个显式终结器,但我更喜欢显式地释放任何资源(即确定性地释放)。对于DTO来说,实际释放资源似乎是不寻常的,因此,如果它不提供故障时的IDisposa

在c#中,我反序列化了一个类型为的对象,该对象使用以下语句实现IDisposable(仅供说明)

好的,序列化程序尝试使用默认的构造函数构造对象,并随后分配所有公共属性和字段。如果出现任何异常,我将无法获得构造的对象


所以,我的问题是,是否有任何方法可以确保自动释放尚未分配的资源。我知道Dispose(bool disposing)-“模式”实现了一个显式终结器,但我更喜欢显式地释放任何资源(即确定性地释放)。

对于DTO来说,实际释放资源似乎是不寻常的,因此,如果它不提供故障时的
IDisposable
支持,我可以理解(我自己的序列化程序也不提供,所以我当然不能批评)

也许可以更改您的类,以便如果它确实有要处置的资源,它会延迟地获取这些资源(即,不只是在反序列化类型时)


XmlSerializer
不支持回调,否则最终回调可能会成为急切加载资源的一个可能选项(尽管有点黑客)。

您的默认构造函数是否执行了需要dispose的操作?如果是,这是一个好主意吗(特别是对于要在xml中序列化的对象)?如果没有,那你为什么还要担心呢?留给垃圾收集器吧

[编辑:删除了关于公共字段的点,因为它不正确]

如果在
XmlSerializer.Deserialize
方法中出现任何异常,我也会让这个答案对它可能具有的任何教育价值可用->阅读Marc的评论。反序列化方法,它将传播到下一个catch方法,并且您的对象(
o
)将不会被分配。因此,除非您在反序列化过程中使用属性设置器分配一些非托管资源,否则我不明白您为什么要关心手动处理对象

但是,如果您的类确实分配了非托管资源,那么正确地实现
IDisposable
将意味着您也将从对象的终结器中释放非托管资源,所以这就足够了。没有其他方法可以对一个没有被分配的对象调用
Dispose()


话虽如此,我必须承认,如果反序列化过程中xml文件不完全有效,XmlSerializer可能会挂起,因此我在反序列化之前进行了架构验证,以确保一切正常。

调用GC.Collect(0,GCCollectionMode.Forced)如何获取异常后?

使用
子句可以确定地释放资源:

using (MyDisposible o = (MyDisposible)s.Deserialize (filepath))
{
 // Do stuff with 0
}
我会问你为什么要这么做。在C#中,您只想确定地释放绑定到外部物理资源(如SQL连接或文件)的内容


垃圾收集器比手动内存管理更有效,允许内存引用直接超出范围以释放内存是一种好的做法。

在C#中,Disposer和Finalizer不是一回事

disposer实现了一个调用,以显式地处置所使用的资源,但不处置其中的内存。需要对象的用户调用此函数

您可以使用C#中的终结器来保证即使您的处理器没有被调用,您也不会泄漏资源。i、 e.Net保证它会在垃圾收集之前运行你的处理器

XmlSerializer在其调用中负责在调用中出现异常时不泄漏内存。如果发生这种情况,那么您将在.Net中发现一个bug,可以随时报告它。如果你调用反序列化,它抛出一个异常,你就无法取回对象,它就消失了


.Net的垃圾收集器可以工作,它是托管语言的免费赠品之一,因为您不必担心清理内存(在大多数情况下),所以您可以更加关注代码的工作,并正确地完成它。

公共字段已分配(当然,虽然您首先不应该有公共字段)它不是一个私有的成员。它不仅仅是你需要考虑的构造函数——它可能在任何时候都失败,它可能与这个类/实例无关。愚蠢的我…我习惯了只有私有字段,我忘记了它的不同……以及其他可能的失败的好点……懒惰的方法听起来像M。最合理的解决方案关于DTO不应拥有资源点的看法是正确的。我试图绕过显式DTO方法,使用现成的dotnet xmlserializer。但是,在我的情况下,这似乎是一个相当大的问题(与往常一样,在尝试xml序列化非平凡类时)---。我认为,如果您遇到这种边缘情况,并且对这种功能有绝对的需求,请查看一个不同的、开放的持久性框架,并对其进行调整。实际上,我没有遇到这种边缘情况。根据Sam的回答-嘿,我有一个可能会工作的;-p(但它不是xml)。为
IDisposable
跟踪所有对象并不难。我不会急于添加此项,但它可能会起作用。我不敢…丑陋的方式你不应该明确强制GC。@Spence:这是什么答案?我看不出有理由相信OP认为两者是相同的。Obw,从未听说过“Disposer”这个词之前,在第1, 2, 3段中回答。4/5回答。我相信我正在处理C++编码器,所以我想澄清一个处理程序和终结器之间的区别,这是跨越那些鸿沟的一个常见错误。“垃圾回收器比手动内存管理更高效,而且它是很好的实践。
using (MyDisposible o = (MyDisposible)s.Deserialize (filepath))
{
 // Do stuff with 0
}