.Net/C# 对象应该对自身调用 Dispose() 吗?

发布于 2024-10-17 20:19:21 字数 880 浏览 8 评论 0原文

下面是同事写的一些示例代码。这对我来说显然是错误的,但我想检查一下。对象是否应该从其自己的方法之一调用其自己的 Dispose() 方法?在我看来,只有对象的所有者/创建者在处理对象而不是对象本身时才应该调用 Dispose()

它是一个 .asmx Web 方法,完成后会调用自身 Dispose()。 (事实上​​,它是一个 Web 方法,这对于一般问题来说可能是偶然的。)在我们的代码库中,我们有时会在其他 Web 服务的方法中实例化 Web 服务类,然后调用它们的方法。如果我的代码这样做来调用此方法,则当该方法返回时该对象将被烘烤,并且我无法再真正使用该对象。

[WebMethod]
public string MyWebMethod()
{
    try
    {
        return doSomething();
    }
    catch(Exception exception)
    {
        return string.Empty;
    }
    finally
    {
        Dispose(true);
    }
}

更新: 找到了一些相关的链接:

我需要在 ASP.NET 中处置 Web 服务引用吗?

处置Web 服务代理类?

Below is some sample code written by a colleague. This seems obviously wrong to me but I wanted to check. Should an object call its own Dispose() method from within one of its own methods? It seems to me that only the owner/creator of the object should call Dispose() when it's done with the object and not the object itself.

It's an .asmx web method that calls Dispose() on itself when it's done. (The fact that it's a web method is probably incidental to the question in general.) In our code base we sometimes instantiate web service classes within methods of other web services and then call methods on them. If my code does that to call this method, the object is toast when the method returns and I can't really use the object any more.

[WebMethod]
public string MyWebMethod()
{
    try
    {
        return doSomething();
    }
    catch(Exception exception)
    {
        return string.Empty;
    }
    finally
    {
        Dispose(true);
    }
}

UPDATE:
Found a few links that are related:

Do I need to dispose a web service reference in ASP.NET?

Dispose a Web Service Proxy class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

捂风挽笑 2024-10-24 20:19:21

当然这不是一个好的做法。调用者应该决定何时结束使用 IDisposable 对象,而不是对象本身。

For sure it's not a good prartice. The caller should decide when he is finished using the IDisposable object, not an object itself.

音盲 2024-10-24 20:19:21

执行“自行处置”操作的正当理由很少。
线程是我经常使用的一种。

我有几个“即发即忘”线程的应用程序。
使用这种方法允许对象自行处置。

这有助于在没有线程管理器进程的情况下保持环境清洁。

There are very few valid reasons to perform a "Self Disposing" action.
Threading is the one I use more than not.

I have several applications that "fire and forget" threads.
Using this methodology allow the object to self dispose.

This helps keep the environment clean without a threading manager process.

九歌凝 2024-10-24 20:19:21

如果我在我的一个项目中看到它,我会问为什么,我 99.9999% 确定我会删除它,无论如何

,这是一种 危险信号/代码气味

if I ever see that in one of my projects, I would ask why and I'm 99.9999% sure that i would remove it anyway

for me this is a kind of red flag / code smells

一梦浮鱼 2024-10-24 20:19:21

对于允许 Dispose 方法执行的操作没有技术限制。它唯一的特别之处是 Dispose 在某些构造中被调用(foreachusing)。因此,Dispose 可以合理地用于将对象标记为不再可用,特别是在调用是幂等的情况下。

然而,由于 Dispose 的语义已被接受,我不会将其用于此目的。如果我想从类本身中将一个对象标记为不再可用,那么我将创建一个可以由 Dispose 或任何其他地方调用的 MarkUnuseable() 方法。

通过将对 Dispose 的调用限制为普遍接受的模式,您可以对所有类中的 Dispose 方法进行更改,并且确信不会意外破坏任何偏离常见模式的代码。

There are no technical restrictions on what a Dispose method is allowed to do. The only thing special about it is that Dispose gets called in certain constructs (foreach, using). Because of that, Dispose might reasonably be used to flag an object as no-longer-useable, especially if the call is idempotent.

I would not use it for this purpose however, because of the accepted semantics of Dispose. If I wanted to mark an object as no-longer-useable from within the class itself, then I would create a MarkUnuseable() method that could be called by Dispose or any other place.

By restricting the calls to Dispose to the commonly accepted patterns, you buy the ability to make changes to the Dispose methods in all of your classes with confidence that you will not unexpectedly break any code that deviates from the common pattern.

妄司 2024-10-24 20:19:21

只需将其删除,但请注意将其放置在调用它的所有对象中。

Just remove it, but take care to dispose it in all object that call it.

调妓 2024-10-24 20:19:21

从技术上讲,是的,如果该“方法”是终结器并且您正在实现 最终确定和 IDisposable 模式 由 Microsoft 指定。

Technically yes, if that "method" is the finaliser and you are implementing the Finalise and IDisposable pattern as specified by Microsoft.

遥远的她 2024-10-24 20:19:21

虽然 .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 建立的通信流。请注意,有关打开套接字的数据实际上是非托管资源,但它不能很好地包装在带有终结器的对象中,因为它通常会被传递给垃圾收集器看不到的东西。

While a .Net object would not normally call Dispose on itself, there are times when code running within an object may be the last thing that expects to be using it. As a simple example, if a Dispose method can handle the cleanup of a partially-constructed object, it may be useful to have a constructor coded something like the following:

Sub New()
  Dim OK As Boolean = False
  Try
    ... do Stuff
    OK = True
  Finally
    If Not OK Then Me.Dispose
  End Try
End Sub

If the constructor is going to throw an exception without returning, then the partially-constructed object, which is slated for abandonment, will be the only thing that will ever have the information and impetus to do the necessary cleanup. If it doesn't take care of ensuring a timely Dispose, nothing else will.

With regard to your particular piece of code, the pattern is somewhat unusual, but it looks somewhat like the way a socket can get passed from one thread to another. There's a call which returns an array of bytes and invalidates a Socket; that array of bytes can be used in another thread to create a new Socket instance which takes over the communications stream established by the other Socket. Note that the data regarding the open socket is effectively an unmanaged resource, but it can't very well be wrapped in an object with a finalizer because it's often going to be handed off to something the garbage-collector can't see.

泼猴你往哪里跑 2024-10-24 20:19:21

不!这是意外行为,违反了最佳实践准则。永远不要做任何意想不到的事情。您的对象应该只执行维护其状态所需的操作,同时为调用者​​保护对象的完整性。调用者将决定何时完成(如果没有其他事情,则由 GC 决定)。

No! It is unexpected behavior and breaks the best practices guidelines. Never do anything that is unexpeceted. Your object should only do what is needed to maintain it's state while protecting the integrity of the object for the caller. The caller will decide when it's done (or the GC if nothing else).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文