2014-10-27 152 views
1

我开发了一个应用程序,可以执行一些操作,例如在关闭应用程序事件时恢复网络适配器设置。该应用程序在win 7 64位下以c#4.0编写,它使用WinAPI来捕捉“控制台关闭事件”。
该应用程序正在抛出“在未知模块中发生未处理的'System.NullReferenceException'类型异常。”当我关闭它,并在我看来是由于事实,在关闭​​控制台事件我做了一些操作。使用setConsoleCtrlHandler,我们可以捕捉到“关闭控制台应用程序”事件,并且我们有一个大约1-2秒的时间窗口来完成我们的操作,但有时这个1-2秒不足以完成我在这个方法中必须做的所有事情。该方法所需时间少于1秒即可完成。这是我使用捕捉关闭事件和操作我在做的时候触发事件的代码:WinAPI CloseEvent抛出空指针异常

//WinAPI method that catches the close event 
static class NativeMethods 
{ 
    public delegate bool HandlerRoutine(CtrlTypes CtrlType); 

    // An enumerated type for the control messages 
    // sent to the handler routine. 
    public enum CtrlTypes 
    { 
     CTRL_C_EVENT = 0, 
     CTRL_BREAK_EVENT, 
     CTRL_CLOSE_EVENT, 
     CTRL_LOGOFF_EVENT = 5, 
     CTRL_SHUTDOWN_EVENT 
    } 

    [DllImport("Kernel32")] 
    public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add); 

    public static bool ConsoleCtrlCheck(CtrlTypes ctrlType) 
    { 
     // Put your own handler here 
     switch (ctrlType) 
     { 
      case CtrlTypes.CTRL_CLOSE_EVENT: 
       Console.WriteLine("Program being closed!"); 
       try 
       { 
        //do stuff 
       } 
       catch(Exception ex) 
       { 
        Console.WriteLine("FAILED"); 
       } 
       break; 
     } 
     return true; 
    } 
} 

//In Program.cs I register to catch the window events: 
NativeMethods.SetConsoleCtrlHandler(new NativeMethods.HandlerRoutine(NativeMethods.ConsoleCtrlCheck), true); 

你对我应该如何避免此问题的任何想法和执行有用的方法应用程序关闭之前?
Thx

+0

请显示更多代码。请显示对“SetConsoleCtrlHandler”的调用。我希望看到你提及代表阻止它被收集。 – 2014-10-27 08:50:35

+0

我添加了其他详细信息,thx – Lucian 2014-10-27 08:55:17

+0

应用程序可以因没有机会清理的奇迹原因而终止。做网络适配器等改变,并期望在退出时进行清理是非常有问题的。 Windows有[Filtering Platform](过滤平台)(http://msdn.microsoft.com/en-us/library/windows/hardware/dn653358(v = vs.85).aspx),它更有可能以您想要的方式执行做。 – 2014-10-27 09:06:40

回答

1

您将委托传递给非托管代码,但不采取措施使该委托保持活动状态。就垃圾收集器所知,只要SetConsoleCtrlHandler返回,就不再有对该委托的引用。代表没有理由让它活下去。

您应该在静态变量中持有对委托的引用,以防止它被收集。