我想在Windows关机发生时正常关闭我的vb.net控制台应用程序。我发现,调用Win32函数SetConsoleCtrlHandler例子,所有的基本上是这样的:检测如何在Windows关机时关闭控制台应用程序
CallbackOnCollectedDelegate:
Module Module1 Public Enum ConsoleEvent CTRL_C_EVENT = 0 CTRL_BREAK_EVENT = 1 CTRL_CLOSE_EVENT = 2 CTRL_LOGOFF_EVENT = 5 CTRL_SHUTDOWN_EVENT = 6 End Enum Private Declare Function SetConsoleCtrlHandler Lib "kernel32" (ByVal handlerRoutine As ConsoleEventDelegate, ByVal add As Boolean) As Boolean Public Delegate Function ConsoleEventDelegate(ByVal MyEvent As ConsoleEvent) As Boolean Sub Main() If Not SetConsoleCtrlHandler(AddressOf Application_ConsoleEvent, True) Then Console.Write("Unable to install console event handler.") End If 'Main loop Do While True Threading.Thread.Sleep(500) Console.WriteLine("Main loop executing") Loop End Sub Public Function Application_ConsoleEvent(ByVal [event] As ConsoleEvent) As Boolean Dim cancel As Boolean = False Select Case [event] Case ConsoleEvent.CTRL_C_EVENT MsgBox("CTRL+C received!") Case ConsoleEvent.CTRL_BREAK_EVENT MsgBox("CTRL+BREAK received!") Case ConsoleEvent.CTRL_CLOSE_EVENT MsgBox("Program being closed!") Case ConsoleEvent.CTRL_LOGOFF_EVENT MsgBox("User is logging off!") Case ConsoleEvent.CTRL_SHUTDOWN_EVENT MsgBox("Windows is shutting down.") ' My cleanup code here End Select Return cancel ' handling the event. End Function
,直到我将其纳入MUY现有程序,当我得到这个例外,这工作正常 消息:对“AISLogger!AISLogger.Module1 + ConsoleEventDelegate :: Invoke”类型的垃圾收集代理进行回调。这可能会导致应用程序崩溃,损坏和数据丢失。在将代理传递给非托管代码时,它们必须由托管应用程序保持活动状态,直到确保它们永远不会被调用。
大量搜索表明问题是由于未引用委托对象造成的,因此超出了范围,因此被垃圾回收器处置。这似乎可以通过在上面的例子中将GC.Collect添加到主循环中并在关闭控制台窗口或按Ctrl-C时获得相同的异常来确认。问题是,我不明白“引用委托”的含义是什么?这听起来像给我分配一个变量的函数?我怎样才能在VB中做到这一点?有很多C#的例子,但我不能将它们转换成VB。
谢谢。
谢谢,汉斯,那很完美。我已经半天试图弄清楚我做错了什么! – Guy 2013-03-10 01:35:15