2017-10-05 54 views
0

背景:VB.NET - 程序退出後控制檯進程保持打開狀態。我如何正確關閉它們?

我正在編寫一個程序,打開交互式控制檯應用程序,偵聽STDOUT/STDERR,並將命令發送到此交互式會話。最後它會發出一個退出命令,這個過程通常會消失。如果用戶點擊關閉按鈕,我會在發出退出命令的類上調用dispose,然後在程序終止之前嘗試強制關閉會話。我注意到,經過一天的測試,我有一堆孤立的進程仍在運行。他們建立並永不放棄。顯然,我犯了一個可怕的錯誤。

問題:

如何確保我的控制檯過程完全死了我的應用程序終止前?

我的處理方法:

Protected Overridable Async Sub Dispose(disposing As Boolean) 
    If _disposed Then Return 

    If disposing Then 
     _handle.Dispose() 
     ' Free any other managed objects here. 
     '   
     If IsConnected Then Await ClosePort().ConfigureAwait(False) 
     If _transmissionCancel IsNot Nothing Then _transmissionCancel.Dispose()   
    End If 

    ' Free any unmanaged objects here. 
    ' 
    If _consoleReader IsNot Nothing Then _consoleReader.Dispose() 
    If _consoleWriter IsNot Nothing Then _consoleWriter.Dispose() 
    If _consoleProcess IsNot Nothing Then _consoleProcess.Dispose() 

    _disposed = True 
End Sub 

注: 的 「ClosePort」 的方法在這裏被稱爲有殺滅和等待:

If Not _consoleProcess.WaitForExit(SocketTimeout) Then 
    _consoleProcess.Kill() 
    _consoleProcess.WaitForExit() 
End If 
+1

使Dispose()異步不太可能達到良好的目的。該程序很少運行足夠長的時間以完成異步代碼。 –

+0

不幸的是,我正在以異步的方式發送退出信號給進程。這應該允許控制檯進程以自己的方式退出。殺死只有在失敗時纔會發生。 – HackSlash

+0

異步關鍵字的添加具有程序員的不幸副作用,不再知道如何解決簡單的異步問題。啓動一個線程,確保它的IsBackground屬性不是False。 –

回答

0

在從@漢斯 - 順便建議;我試圖從Dispose方法中刪除「Async」修飾符,並在完成處理之前同步等待任務完成。我完成了我的功能任務,並讓它開始。這似乎工作,但現在我的程序不會結束,當我點擊關閉按鈕。我的代碼從「.start」跳轉到「End Using」,但Dispose方法停止,將控制權交還給用戶界面。如果我再次點擊close,那麼dispose方法會再次觸發,並且我的程序會完全關閉。

我張貼此作爲答案,因爲它似乎已經解決了我原來的問題,這是我目前的答案。但是,我不想將此標記爲解決方案,因爲我必須點擊關閉兩次以結束我的程序。我做了什麼?

我仍然對其他解決方案開放。

Protected Overridable Sub Dispose(disposing As Boolean) 
    If _disposed Then Return 

    If disposing Then 
     _handle.Dispose() 
     ' Free any other managed objects here. 
     '   
     If IsConnected Then     
      Using holdOnAMinute As Task = Task.Run(Function() ClosePort())     
       holdOnAMinute.Start() 
       holdOnAMinute.Wait(SocketTimeout) 
      End Using 
     End If 
    End If 
    ' Free any unmanaged objects here. 
    ' 
    If _consoleReader IsNot Nothing Then _consoleReader.Dispose() 
    If _consoleWriter IsNot Nothing Then _consoleWriter.Dispose() 
    If _consoleProcess IsNot Nothing Then _consoleProcess.Dispose() 
    If _transmissionCancel IsNot Nothing Then _transmissionCancel.Dispose() 

    _disposed = True 
End Sub 
相關問題