VB.NET - 控制台进程在程序退出后保持打开状态。如何正确关闭它们?
VB.NET - Console processes being left open after program exit. How do I close them correctly?
背景:
我正在编写一个程序来打开一个交互式控制台应用程序,监听 STDOUT/STDERR,并向这个交互式会话发送命令。最后它会发出退出命令,进程通常会消失。如果用户单击我在 class 上调用 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
根据@hans-passant 的建议;我试图从我的 Dispose 方法中删除 "Async" 修饰符,并在完成处置之前同步等待任务完成。我为我的功能制定了任务并告诉它开始。这似乎有效,但现在当我单击关闭按钮时,我的程序并没有结束。我的代码从“.start”跳转到 "End Using",但随后 Dispose 方法停止,将控制权传递回 UI。如果我第二次单击关闭,则会再次触发 dispose 方法并且我的程序会干净地关闭。
我post这是一个答案,因为它似乎已经解决了我原来的问题,而且这是我目前的答案。但是,我不想将此标记为解决方案,因为我必须单击两次关闭才能结束我的程序。我做了什么?
我仍然对其他解决方案持开放态度。
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
背景:
我正在编写一个程序来打开一个交互式控制台应用程序,监听 STDOUT/STDERR,并向这个交互式会话发送命令。最后它会发出退出命令,进程通常会消失。如果用户单击我在 class 上调用 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
根据@hans-passant 的建议;我试图从我的 Dispose 方法中删除 "Async" 修饰符,并在完成处置之前同步等待任务完成。我为我的功能制定了任务并告诉它开始。这似乎有效,但现在当我单击关闭按钮时,我的程序并没有结束。我的代码从“.start”跳转到 "End Using",但随后 Dispose 方法停止,将控制权传递回 UI。如果我第二次单击关闭,则会再次触发 dispose 方法并且我的程序会干净地关闭。
我post这是一个答案,因为它似乎已经解决了我原来的问题,而且这是我目前的答案。但是,我不想将此标记为解决方案,因为我必须单击两次关闭才能结束我的程序。我做了什么?
我仍然对其他解决方案持开放态度。
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