2010-08-12 74 views
0

我有一個需要啓動子進程並通過標準輸入和輸出與它通信的進程。子進程應該能夠自動終止;但是,我無法正確關閉流。C# - 如何在進程退出時關閉標準輸入和輸出流?

這裏是孩子/ 「客戶端」 過程中的相關代碼:

// This is started in a separate thread 
private void watchStandardInput() { 
    string line = null; 
    do { 
     try { 
      line = Console.ReadLine(); 
     } catch (IOException) { 
      return; 
     } 
     lock (inputWatcher) { 
      switch (line) { 
       // process command 
      } 
     } 
    } while (line != null); 
} 

// This is called from the main thread 
private void updateStatus(string statusMessage) { 
    lock (inputWatcher) { 
     Console.WriteLine(statusMessage); 
    } 
} 

而這裏的 「服務器」 代碼:

// This is in the main thread 
using (StreamReader sr = process.StandardOutput) { 
    while (!process.HasExited) { 
     processOutput(sr.ReadLine()); 
    } 
} 

// Finally, commands are sent in a separate thread. 

現在對於我有問題:當子進程應該退出時,服務器停留在sr.ReadLine(),客戶端停留在Console.ReadLine()。我究竟做錯了什麼?

+0

它應該如何退出?它看起來就像它剛剛沒有退出一樣(我假設他們都在等待輸入是它的標準狀態?還是這是一個不尋常的狀態?在粗略的水平上,我會想象設置一個名爲「兒童關閉」的屬性,可以檢查無處不在,以確保它在嘗試關閉時不會嘗試讀取,但有可能是更優雅的解決方案,我只是沒有足夠好地瞭解您的程序流程,以便知道他們目前的狀態。) – Chris 2010-08-12 15:47:33

+0

等待輸入是標準狀態。子進程知道應該何時關閉,但父進程不知道。我可以讓孩子做一個'Console.WriteLine(「嘿,我正在關閉」),但這很醜陋,會破壞現有的代碼。 – jnylen 2010-08-12 15:53:02

+0

我還應該提到,子程序正在_trying_正常關閉 - 但是線程在我上面提到的調用中仍然被阻止。 – jnylen 2010-08-12 15:57:28

回答

1

確保執行ReadLine()的客戶端線程將IsBackground設置爲true。不要在這個線程上做一個Abort()/ Join()。關閉所有非後臺線程。我發現即使將IsBackground設置爲true,在後臺線程上執行Abort()/ Join()也會導致我的測試應用程序等待輸入,但是,取消Abort()/ Join()並退出正常工作正常。

+0

我可以在必要時通過在子進程中調用'Environment.Exit'來獲得某些工作,但這是一個更好的解決方案,我不知道。謝謝。 – jnylen 2010-08-12 18:40:22

相關問題