2010-06-10 101 views
6

有没有一种方法可以监视使用dll的应用程序何时关闭? DLL和应用程序都是C#,Windows Forms也不例外。需要知道应用程序何时关闭

我可以检查主应用程序何时关闭,但我希望DLL能看到“嘿程序正在关闭并释放我,我应该在我死前真正做到这一点”。

任何方式来做到这一点?或者我坚持让应用程序菜“在你死之前做这个”?

+1

你为什么需要这个?被管理的DLL通过垃圾回收器自动释放他们的资源。如果您需要释放非托管资源,请使用Finalization。 – 2010-06-10 06:51:21

+0

@FractalizerR:使用终结器释放资源是*不推荐使用,因为它是不确定的。相反,对象应该实现'IDisposable'。 – 2010-06-10 07:05:01

回答

8

也许AppDomain.ProcessExit事件会适合你?注意(从文档),虽然以下几点:

所有 ProcessExit事件处理程序的总执行时间是有限的, 一样的 所有终结的总执行时间是在工艺的限制 关机。默认值是两秒。 非托管主机可以通过调用 ICLRPolicyManager::SetTimeout方法 和OPR_ProcessExit枚举 值来更改此执行时间。

+0

谢谢。我试图实现它,但是我不认为这个事件会被调用。不知道是否有一个技巧,使其工作。我做了 AppDomain.CurrentDomain.ProcessExit + = new EventHandler(CurrentDomain_ProcessExit); 并且据我所知,它不会进入CurrentDomain_ProcessExit。我的检查方式是我想要的代码,并且只是在Winform消息框到达时显示它自己。该框应该出现然后消失,或出现然后挂起正常关机的应用程序。但都没有发生。 :( – Nick 2010-06-10 07:10:24

+0

@Nick:你能分享一下这个实现的细节吗(例如更新这个问题)我试用了它,并且它按照预期工作 – 2010-06-10 08:25:10

+0

它对我有用(TM),然后是第二个第三次尝试它停止工作了!? 我正在通过Ctrl-C检测和优雅退出来完成我的过程 – gatopeich 2012-08-13 15:23:06

1

我们不知道您的代码的细节,但事实是您的类库需要知道该进程何时退出可能表明您的应用程序存在设计缺陷。

如果您需要释放资源或以确定性方式清理其他内容,您应该查看IDisposable界面。如果您的库公开的类实现了此接口,调用方可以轻松地声明它们不再需要dll功能,请致电Dispose()

也许一个良好的起点,进一步阅读的是下面的文章:

例如,你可以有下面的类在类库:

using System; 
using System.IO; 

public class ResourceManager : IDisposable 
{ 
    private Stream _resource; 
    private bool _disposed; 

    public void Dispose() 
    { 
     Dispose(true); 

     // Use SupressFinalize in case a subclass 
     // of this type implements a finalizer. 
     GC.SuppressFinalize(this); 
    } 

    public void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       Console.WriteLine("Exiting Process. Cleaning up."); 
       // free resources here 
       if (_resource != null) 
        _resource.Dispose(); 
       Console.WriteLine("Object disposed."); 
      } 

      // Indicate that the instance has been disposed. 
      _resource = null; 
      _disposed = true; 
     } 
    } 
} 

在你的主模块,那么你可以通过以下方式使用;该using声明将保证Dispose()方法被称为:

using System; 
using System.Windows.Forms; 

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     using (ResourceManager manager = new ResourceManager()) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } 
} 
+0

它是一个设备驱动程序,因此需要释放设备,并且如果可能,在应用程序时将其设置回中性状态因此我需要它在DLL中 当一个程序使用dll时,它可能不会被称为一次性的,它可能会离开它,它会被我自己用在我的程序以及其他可能没有相同编码的程序 – Nick 2010-06-10 07:12:27

+0

@Nick:释放未激活的资源(例如您的设备)正是使用情况g'IDisposable()'。 – 2010-06-10 07:26:32

+0

但是,如果人们不使用处置或使用,那么它不会被称为正确? – Nick 2010-06-10 10:41:56

0

AppDomain.ProcessExit将“正常”的工作,但并不guarateed如果一个进程是由任务管理器,例如终止火。因此,如果您的设备驱动程序需要释放大量资源等,它可能并不理想(也就是说,只有在GC完成之后才能释放它们)。

请参阅Rick Stahls blog了解更多详情。

0

如果是控制台应用程序,则需要按照this question中的接受答案进行操作。 最好用IDisposable接口开发。

相关问题