我想在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