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