2017-10-05 472 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 
相关问题