【问题标题】:Calling Environment.Exit() Within a Using Block在 Using 块中调用 Environment.Exit()
【发布时间】:2012-10-31 19:08:38
【问题描述】:

如果我有一个控制台应用程序,其代码如下:

using (DisposableObject object = new DisposableObject())
{
   if (a condition)
     Environment.Exit(0);

   // Do Stuff
}

我的物品会被妥善处理吗?还是在对象被清理之前线程就死掉了?

【问题讨论】:

  • 请注意,如果您要关闭应用程序,即使对象未 Disposed,您实际上也不会泄漏内存(因为一旦进程终止,进程受保护的内存空间将完全释放。)如果 Disposal 具有更持久的副作用(例如提交到数据库或超出流程范围的内容),其他事情可能会出错。
  • @DanBryant 未释放的资源不会泄漏托管内存。如果非托管资源是非托管内存(可能是由于与非托管语言的互操作),那么您可能有未释放的内存。
  • 我实际上是在 SqlConnection 上使用它,但 using 块嵌套在另外两个(SharePoint 对象)中。我只是想确保 Dispose() 方法会被调用,因为不处理 SP 对象会在日志中生成错误。
  • 嗯...也许是时候重新考虑 Environment.Exit() 的做事方法了?
  • 我总是可以抛出异常。

标签: c# console-application idisposable


【解决方案1】:

您的应用程序将终止,此时所有托管内存都将被释放。

生成的finally 块不会执行,因此不会调用任何Dispose 方法,因此任何非托管资源很可能不会被释放。

Don't Blindly Count on a Finalizer

【讨论】:

  • // Do Stuff 代码会被执行吗? Environment.Exit(0); 到底是做什么的?
  • // Do Stuff 不会被执行。 Environment.Exit(0) 杀死线程并从 main 返回 0。
  • @OlivierJacot-Descombes - // Do Stuff 不会执行。该调用只是终止进程(返回错误代码 - 传入的 int)。
  • @rj - 你担心内存泄漏。一般来说,这没有多大意义,终止的进程不会泄漏内存。 IDisposable 也与内存无关。您唯一需要担心的是非常小的极端情况,其中类有一个终结器,并且当终结器清理而不是 Dispose() 时,它会做一些不同的事情。不要编写终结器。
  • 我没有写日志。它们是 SharePoint 对象。如果您不进行处置,SharePoint 会为您处理,但会在日志中生成一个错误,指出您没有正确处置。我现在正在测试(试图强制这种行为)。
【解决方案2】:

操作系统知道的资源通常会在应用程序退出时被清理。操作系统不知道的资源一般不会被清理。

例如,一些使用数据库并且需要实现与数据库服务器直接支持的任何东西不同的锁定范例的程序可能会使用一个或多个“LockedResources”表来跟踪应该锁定哪些资源。需要获取资源的代码会锁定“LockedResources”表,更新它以显示需要锁定的资源,然后释放它;对“LockedResource”表的操作通常会很快(因此“LockedResource”表只会短暂锁定),即使应用程序需要长时间持有实际资源。但是,如果应用程序执行 Environment.Exit 而“LockedResources”表表示它拥有资源,则操作系统将不知道如何更新“LockedResources”表以取消此类所有权。

一般来说,即使客户端应用程序意外死机,数据库应用程序之类的东西也应该被设计成健壮的。例如,可能有一个活动客户端表,每个活动客户端都持有一个标识自己的记录的锁。如果想要使用资源的客户端注意到“LockedResources”表已将其签出给其他客户端,则前一个客户端可以检查以确保后一个客户端在“活动客户端”表中的条目仍然被锁定。如果不是,它可能会认为有问题的客户端已经死亡并采取适当的措施(认识到死亡的客户端可能已将其资源置于不良状态)。另一方面,如果客户意外死亡,数据库应该被设计为健壮的事实并不意味着它们总是如此。资源放弃不是一件好事,即使它通常是可生存的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多