0
我在下面編寫了我的程序的簡化版本。進程A啓動一個子進程(進程B)。我使用匿名管道來寫入有關在進程B上運行的方法進度的信息。同時,我在進程A中有一個函數,它不斷從流中讀取數據,以查看是否有來自管道的新更新。如果存在,則更新流程A上的表單以反映進度。這可以按預期工作,但我想知道是否有更好的方法來實現這一點,而不必持續檢查流,以查看是否有任何新的更新進展。如何在使用IPC C時有效地讀取管道流#
/////////////////
///Process A ////
/////////////////
public void LaunchProcessB()
{
using (AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream(PipeDirection.In,
HandleInheritability.Inheritable))
{
var _Process = new Process();
_Process.StartInfo.FileName = exeString;
_Process.StartInfo.Arguments = pipeServer.GetClientHandleAsString()
_Process.StartInfo.RedirectStandardOutput = true;
_Process.StartInfo.RedirectStandardInput = true;
_Process.StartInfo.CreateNoWindow = true;
_Process.StartInfo.UseShellExecute = false;
_Process.Start(); //launches process B
pipeServer.DisposeLocalCopyOfClientHandle();
using (StreamReader sr = new StreamReader(pipeServer))
{
try
{
while (true)
{
string temp = sr.ReadLine();
if (temp == null) break;
int result;
if (Int32.TryParse(temp, out result))
ShowDocumentProgress(result);
else ShowProgress(temp);
}
}
catch (Exception)
{
//error occured when reading from stream.
}
}
if (!_Process.Responding && !_Process.HasExited)
{
_Process.Kill();
return;
}
_Process.WaitForExit(10000);
}
}
private void ShowProgressPercent(int percentage)
{
if (percentage > currentPercentage)
{
progressBar.Value = percentage;
}
}
private void ShowProgress(string progressString)
{
labelMessage.Text = progressString;
}
/////////////////
///Process B ////
/////////////////
private StreamWriter _progressWriter;
private PipeStream _progressPipe;
static int Main(string[] args)
{
using (progressPipe = new AnonymousPipeClientStream(PipeDirection.Out, args[0]))
using (_progressWriter = new StreamWriter(_progressPipe))
{
RunLongProcess()
}
}
private void RunLongProcess()
{
//attaches events to PercentProgress and StageProgress methods.
}
private void PercentProgress(int percentage)
{
_progressWriter.WriteLine(percentage.ToString());
_progressPipe.WaitForPipeDrain();
}
private void StageProgress(string stage)
{
_progressWriter.WriteLine(stage);
_progressPipe.WaitForPipeDrain();
}
感謝您的建議。我更新了我的代碼以反映它們。我仍然在while循環中保留pipeServer.IsConnected檢查,以避免拋出大多數異常。我還添加了一個檢查以確保該流程仍然響應。 – user2481095
這在兩種方式中被破壞:_Process.Responding是基於GUI的,所以可能不正確。即使您需要這些語義,如果進程無響應,您也可能會丟棄緩衝的數據。其次,即使pipeServer.IsConnected變爲false,流式讀取器可能會緩衝數據,導致丟失數據。 'if(temp == null)continue;'this should be'... break;'。您幾乎從不會在這裏看到異常,因爲大部分時間遠程句柄將被關閉,您將收到空值。 – usr
'_Process.Kill(); return;'需要WaitForExit很好,因爲查殺不是即時的。 IO可能會徘徊。另外,你不應該因爲關閉管道而殺死進程。它可能仍在做着事情並關閉。也許只有在WaitForExit返回false後才能殺死? – usr