背景:
我正在编写一个打开交互式控制台应用程序的程序,侦听STDOUT / STDERR,并向此交互式会话发送命令。最后它将发出一个退出命令,该过程通常会消失。如果用户单击关闭按钮,我会在发出exit命令的类上调用dispose,然后在程序终止之前尝试强制关闭会话。我注意到经过一天的测试后,我仍然有一堆孤立的进程在运行。他们积累起来,永不放弃。显然,我犯了一个可怕的错误。
问题:
在应用程序终止之前,如何确保我的控制台进程完全停止?
MY DISPOSE METHOD:
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”方法具有kill和wait:
If Not _consoleProcess.WaitForExit(SocketTimeout) Then
_consoleProcess.Kill()
_consoleProcess.WaitForExit()
End If
答案 0 :(得分:0)
来自@ hans-passant的建议;我试图删除" Async"来自我的Dispose方法的修饰符,并在完成处理之前同步等待任务完成。我完成了我的功能任务并告诉它开始。这似乎有效但现在我的程序在单击关闭按钮时不会结束。我的代码跳过" .start"到"结束使用"但随后Dispose方法停止,将控制权传递回UI。如果我再次单击关闭,则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