VB.NET - 程序退出后控制台进程保持打开状态。如何正确关闭它们?

时间:2017-10-05 16:22:26

标签: vb.net process dispose

背景:

我正在编写一个打开交互式控制台应用程序的程序,侦听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

1 个答案:

答案 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