VB.NET - 程序退出后控制台进程保持打开状态。我如何正确关闭它们?
问题描述:
背景: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
答
在从@汉斯 - 顺便建议;我试图从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
使Dispose()异步不太可能达到良好的目的。该程序很少运行足够长的时间以完成异步代码。 –
不幸的是,我正在以异步的方式发送退出信号给进程。这应该允许控制台进程以自己的方式退出。杀死只有在失败时才会发生。 – HackSlash
异步关键字的添加具有程序员的不幸副作用,不再知道如何解决简单的异步问题。启动一个线程,确保它的IsBackground属性不是False。 –