2012-09-24 22 views
1

Im使用Stockfish遊戲引擎爲人類與電腦遊戲提供動力。 下面是代碼的第一部分:閱讀StandardInput停止代碼執行而不會中斷應用程序

Process _proc= new Process(); 
_proc.StartInfo = new ProcessStartInfo(path); 
_proc.StartInfo.RedirectStandardInput = true; 
_proc.StartInfo.RedirectStandardOutput = true; 
_proc.StartInfo.UseShellExecute = false; 
_proc.StartInfo.CreateNoWindow = true; 
_proc.Start(); 
_proc.StandardInput.WriteLine("uci"); 
_proc.StandardInput.WriteLine("ucinewgame"); 

此時一切正常,但是當我嘗試讀取StandardOutput一些奇怪的情況發生。

string result = _proc.StandardOutput.ReadToEnd(); 

Stockfish.exe程序彈出,我的應用程序正在運行,但該行代碼後不執行。當我按下暫停,它指向這一行:

enter image description here

如果我使用:

while (!_proc.StandardOutput.EndOfStream) 
{ 
    result += _proc.StandardOutput.ReadLine(); 
} 

同樣的事情發生只在while語句。結果在那裏有完整的價值,所有的文本都寫入它。

有沒有什麼辦法可以在沒有異步讀取的情況下解決這個問題?

端問題:

由於這是單例類的一部分,用於在整個ASP.NET應用程序,我不覺得自己像使用異步讀取,因爲林不知道我怎樣才能保護(有鎖)多線程寫入它。另外,我不知道如何停止當前線程,因爲命令的處理可以持續10秒。

我不喜歡使用Thread.Sleep()來不斷檢查讀取輸出的結束,而不是優雅。

考慮到側面的問題,如果異步只是解決方案,我該如何避免多線程問題?

我的線程知識很薄弱,所以在給線程相關答案時請記住這一點。謝謝。

回答

0

StandardOutput.ReadToEnd的呼叫將阻止,直到此過程結束。這裏的目標是讀取,處理和響應您收到它們時產生的各種文本命令?
你必須通過異步閱讀來解決這個問題。

例如,您可以將監聽器設置爲Process.OutputDataReceived。然後致電Process.BeginOutputReadLine開始閱讀。您的代碼將繼續執行。同時,.NET Framework將在單獨的線程上處理傳入的文本消息。

+0

問題是,當我使用ReadLine()時,只要有線,它就會工作。如果我在沒有更多引擎返回的文本時使用它,它會像圖片中那樣打破。最糟糕的是,我不知道有多少行,並且沒有辦法獲得長度或檢測數據結束。 我使用了異步aproach,它工作良好,程序沒有進入「死鎖」,但它會產生其他問題,如:我的程序繼續,但引擎沒有返回所有數據。 –