2017-10-05 11 views
0

背景:VB.NET - プログラム終了後にコンソールプロセスが開いたままになっています。正しく閉じるにはどうしたらいいですか?

私は対話型コンソールアプリケーションを開き、STDOUT/STDERRを待ち受け、この対話型セッションにコマンドを送信するプログラムを書いています。最後にexitコマンドを発行し、通常はプロセスが終了します。ユーザーが閉じるボタンをクリックすると、exitコマンドを発行したクラスでdisposeを呼び出し、プログラムが終了する前に強制的にセッションを終了しようとします。私はテストの日の後、私は孤立したプロセスの束がまだ実行していることに気付きます。彼らは築き上げて、決して終わらない。明らかに、私はひどい間違いを犯しました。

質問:私は私のコンソールプロセスが私のアプリケーションが終了する前に、完全に死んでいることを確認するにはどうすればよい

MY 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

asyncキーワードの追加は、プログラマーが単純な非同期問題の解決方法を知らなくても残念な副作用をもたらしました。スレッドを開始し、IsBackgroundプロパティがFalseでないことを確認します。 –

答えて

0

を。私はDisposeメソッドから "Async"モディファイアを削除しようとしましたが、処分を完了する前にタスクが完了するのを同期して待っていました。私は自分の仕事の仕事をして、それを始めるように言った。これは動作するように見えますが、閉じるボタンをクリックしてもプログラムが終了しません。私のコードは ".start"から "End Using"にジャンプしますが、Disposeメソッドは停止し、コントロールをUIに戻します。もう一度closeをクリックすると、disposeメソッドが再び起動し、プログラムが正常に終了します。

これは私の元の問題を解決したように見えるので、私はこれを答えとして投稿し、それは私の現在の答えです。しかし、私はプログラムを終了するために2回閉じる必要があるので、これを解決策としてマークしたくありません。私が何をした?

私はまだ他のソリューションに対応しています。

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 
関連する問題