以下是一位同事撰写的示例代码。这对我来说显然是错的,但我想检查一下。对象是否应该从其自己的方法中调用自己的 Dispose()方法?在我看来,只有对象的所有者/创建者在完成对象而不是对象本身时才应该调用 Dispose()。
这是一个.asmx网络方法,当它完成时会调用 Dispose()。 (事实上,这是一个Web方法可能是一般问题的偶然事实。)在我们的代码库中,我们有时在其他Web服务的方法中实例化Web服务类,然后调用它们上的方法。如果我的代码执行此操作来调用此方法,则该方法返回时该对象是toast,并且我无法再使用该对象。
[WebMethod]
public string MyWebMethod()
{
try
{
return doSomething();
}
catch(Exception exception)
{
return string.Empty;
}
finally
{
Dispose(true);
}
}
更新: 找到了一些相关的链接:
答案 0 :(得分:34)
当然,这不是一个好的表现。调用者应该决定何时使用IDisposable对象,而不是对象本身。
答案 1 :(得分:4)
如果我在其中一个项目中看到过,我会问为什么,我99.9999%确定我会删除它
对我而言,这是一种red flag / code smells
答案 2 :(得分:3)
执行“自我处置”操作的正当理由非常少。 线程是我最常使用的。
我有几个“发射并忘记”线程的应用程序。 使用这种方法可以使对象自行处理。
这有助于在没有线程管理器进程的情况下保持环境清洁。
答案 3 :(得分:1)
对Dispose方法允许执行的操作没有技术限制。唯一特别之处在于Dispose在某些构造中被调用(foreach
,using
)。因此,可以合理地使用Dispose将对象标记为不再可用,特别是如果调用是幂等的。
然而,由于Dispose的语义被接受,我不会将它用于此目的。如果我想在对象本身内标记一个不再可用的对象,那么我将创建一个可以被Dispose或任何其他地方调用的MarkUnuseable()方法。
通过将对Dispose的调用限制为普遍接受的模式,您可以放心地更改所有类中的Dispose方法,并确保不会意外地破坏任何偏离公共模式的代码。
答案 4 :(得分:0)
只需删除它,但要注意将其丢弃在所有调用它的对象中。
答案 5 :(得分:0)
技术上是的,如果该“方法”是终结者,并且您正在实施Microsoft指定的Finalise and IDisposable pattern。
答案 6 :(得分:0)
虽然.Net对象通常不会自己调用Dispose,但有时候在对象中运行的代码可能是最后一个期望使用它的东西。举个简单的例子,如果Dispose方法可以处理部分构造的对象的清理,那么构造函数的编码可能会很有用,如下所示:
Sub New() Dim OK As Boolean = False Try ... do Stuff OK = True Finally If Not OK Then Me.Dispose End Try End Sub
如果构造函数在没有返回的情况下抛出异常,那么部分构造的对象(将被放弃)将是唯一能够获得必要清理的信息和动力的对象。如果它不能确保及时处理,那么别的什么都不会。
关于你的特定代码片段,模式有点不寻常,但它看起来有点像套接字从一个线程传递到另一个线程的方式。有一个调用返回一个字节数组并使一个Socket无效;该字节数组可以在另一个线程中用于创建一个新的Socket实例,该实例接管由另一个Socket建立的通信流。请注意,有关open socket的数据实际上是一个非托管资源,但它不能很好地包含在带有终结器的对象中,因为它经常会被传递给垃圾收集器无法看到的东西。
答案 7 :(得分:0)
没有!这是意外行为,违反了最佳做法指南。永远不要做任何未被发现的事情。您的对象应该只执行维护其状态所需的操作,同时保护调用者的对象的完整性。调用者将决定何时完成(或者如果没有别的话)。