简体   繁体   English

如何以另一种方法正确处理本地创建的 object?

[英]How to properly dispose locally created object in another method?

So I have a class which implements IDisposable, and I have several methods (in another class) which follow the pattern below:所以我有一个实现 IDisposable 的 class,并且我有几个方法(在另一个类中)遵循以下模式:

public void SomeMethod()
{
    DisposableObject disposableObject = new DisposableObject();

    // Do some stuff with the object

    SomeOtherMethod(disposableObject);
    disposableObject.Dispose();
}

While all of these methods do different things, they all call SomeOtherMethod at the end, which does a few more things with the disposable object before it's no longer needed.虽然所有这些方法都做不同的事情,但它们最后都调用SomeOtherMethod ,在不再需要一次性 object 之前,它会做更多的事情。 When I move disposableObject.Dispose();当我移动disposableObject.Dispose(); into SomeOtherMethod , Visual Studio gives me a message saying: " Use recommended dispose pattern to ensure that object created by 'new DisposableObject()' is disposed on all paths: using statement/declaration or try/finally "进入SomeOtherMethod ,Visual Studio 给我一条消息说:“使用推荐的处置模式来确保由‘new DisposableObject()’创建的 object 被处置在所有路径上:使用语句/声明或尝试/最终

This message appears regardless of whether or not I pass the disposable object to SomeOtherMethod using the ref keyword.无论我是否使用ref关键字将一次性 object 传递给SomeOtherMethod ,都会出现此消息。

My question is, will that object be disposed as long as SomeOtherMethod calls Dispose() on it?我的问题是,只要SomeOtherMethod在其上调用Dispose() ,object 是否会被处置? I'm assuming it will, and Visual Studio continues to send the message simply because it isn't "aware" of what's happening to that object in subsequent methods, but I'd love to get some confirmation on that!我假设它会,并且 Visual Studio 继续发送消息只是因为它不“知道”在后续方法中 object 发生了什么,但我很想得到一些确认!

It may be disposed or may be not, depends on the fact whether the execution will reach the Dispose invocation or not and that's because an exception can be thrown before the Dispose is called.它可能被释放或不被释放,取决于执行是否会到达Dispose调用,这是因为在调用Dispose之前可能会引发异常。 Using try finally construction explicitly or implicitly by using keyword ensures that it will be called for any scenario and that's why VS gives you the warning.通过using关键字显式或隐式地使用try finally构造可确保在任何情况下都会调用它,这就是 VS 向您发出警告的原因。

No matter where one call the Dispose() , it is called.无论在哪里调用Dispose() ,它都会被调用。

Not using the language keyword using for the disposable pattern, therefore moving the dispose in another method, is an anti-pattern, therefore it is a bad practice and a source of potential problems.不使用语言关键字using用于一次性模式,因此将 dispose 移动到另一种方法中,是一种反模式,因此它是一种不好的做法,也是潜在问题的根源。

You can only remove the warning by adding the warning number in the project build settings.您只能通过在项目构建设置中添加警告编号来删除警告。

The method Dispose() doesn't destroy the object. Dispose()方法不会破坏 object。

The dispose pattern is only for freeing unmanaged resources like windows handle and shared memories. dispose 模式仅用于释放非托管资源,例如 windows 句柄和共享内存。

After a call to Dispose() you still have the object and so the reference to the object that remains referenced in the managed memory.在调用Dispose()之后,您仍然拥有 object,因此对 object 的引用仍然在托管 memory 中引用。

Dispose() is made to be called once time at the end of object usage and no more. Dispose()在 object 使用结束时被调用一次,仅此而已。

The compiler send you a warning because you break the standard behavior of the pattern usage that is to use the using keyword.编译器会向您发送警告,因为您破坏了使用using关键字的模式使用的标准行为。

And breaking standards can be source of problems.违反标准可能是问题的根源。

The using of disposable objects standard is made to avoid bugs by letting the compiler generates the try {... } finally { Dispose() } block to be sure that Dispose() is correctly called in the right place to avoid mistakes.使用一次性对象标准是为了避免错误,让编译器生成try {... } finally { Dispose() }块以确保在正确的位置正确调用Dispose()以避免错误。

So avoid calling the Dispose() directly.所以避免直接调用Dispose()

Unless you are sure of what you do, prefer using:除非您确定自己在做什么,否则最好使用:

public void SomeMethod()
{
  using ( DisposableObject disposableObject = new DisposableObject() )
  {
    // Do some stuff with the object
    SomeOtherMethod(disposableObject);
  }
}

And your code may be robust.而且您的代码可能很健壮。

will that object be disposed object 会被处置吗

Sorry, but that's a meaningless question.对不起,这是一个毫无意义的问题。 The CLR does not keep track of whether an object has had its “dispose” method called or not (see Will the Garbage Collector call IDisposable.Dispose for me? ) CLR 不会跟踪 object 是否调用了它的“dispose”方法(请参阅垃圾收集器会为我调用 IDisposable.Dispose 吗?

As a general rule, it is always much nicer (readable/ maintainable / less-bug-prone / etc) that a method that creates an issue should also be the one that cleans up after itself.作为一般规则,创建问题的方法也应该是自行清理的方法总是更好(可读/可维护/不易出错/等)。 As you've just found, this pattern also allows automated checking by the compiler - and again, it is also a good rule to ensure that your code compiles cleanly without errors OR WARNINGS.正如您刚刚发现的那样,此模式还允许编译器进行自动检查 - 同样,它也是确保您的代码干净地编译而没有错误或警告的好规则。

In this case, the warning is giving you a couple of ways to implement this cleanly;在这种情况下,警告为您提供了几种干净地实现它的方法; personally, I would prefer the “using” clause (so avoiding having to have an explicit call to “dispose”) like:就个人而言,我更喜欢“使用”子句(因此避免必须明确调用“处置”),例如:

 public void SomeMethod()
 {
     using (DisposableObject disposableObject = new DisposableObject() )
      {

           // Do some stuff with the object

           SomeOtherMethod(disposableObject);
       }

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM