Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在使用IPC时有效地读取管道流#_C#_Stream_Ipc_Named Pipes - Fatal编程技术网

C# 如何在使用IPC时有效地读取管道流#

C# 如何在使用IPC时有效地读取管道流#,c#,stream,ipc,named-pipes,C#,Stream,Ipc,Named Pipes,我在下面写了我的程序的简化版本。流程A启动子流程(流程B)。我使用匿名管道来编写进程B上运行的方法的进度信息。同时,我在进程a中有一个函数,该函数不断地从流中读取数据,以查看是否有新的更新从管道中传入。如果有,则更新流程A上的表格以反映进度。这正如预期的那样工作,但是我想知道是否有更好的方法来实现这一点,而不必不断检查流以查看是否有任何新的进度更新 ///////////////// ///Process A //// ///////////////// public void LaunchP

我在下面写了我的程序的简化版本。流程A启动子流程(流程B)。我使用匿名管道来编写进程B上运行的方法的进度信息。同时,我在进程a中有一个函数,该函数不断地从流中读取数据,以查看是否有新的更新从管道中传入。如果有,则更新流程A上的表格以反映进度。这正如预期的那样工作,但是我想知道是否有更好的方法来实现这一点,而不必不断检查流以查看是否有任何新的进度更新

/////////////////
///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条件不是必需的。只需读取,直到temp为null。这是流的结束信号

将此设置为
while(true)
循环

我认为您还需要添加异常处理来捕获终止和断开管道的进程<代码>_Process.HasExited&&pipeServer.IsConnected是不够的,因为它可能为true,但在测试后会立即切换为false


我还将在末尾添加一个
WaitForExit
,以确保系统在继续之前处于静止状态。

while条件不是必需的。只需读取,直到temp为null。这是流的结束信号

将此设置为
while(true)
循环

我认为您还需要添加异常处理来捕获终止和断开管道的进程<代码>_Process.HasExited&&pipeServer.IsConnected是不够的,因为它可能为true,但在测试后会立即切换为false


我还想在最后添加一个
WaitForExit
,以确保系统在继续之前处于静止状态。

感谢您的建议。我更新了代码以反映它们。我仍然将pipeServer.IsConnected检查保留在while循环中,以避免抛出大多数异常。我还添加了一个检查,以确保流程仍然具有响应性。这在两个方面被打破:_process.Responding是基于GUI的,所以可能不正确。即使您需要这些语义,如果进程没有响应,也可能会丢弃缓冲数据。其次,即使pipeServer.IsConnected变为false,streamreader也可能有数据缓冲区,您将丢失这些数据<代码>如果(临时==null)继续这应该是
。。。中断。在这里,您几乎永远不会看到异常,因为大多数时候远程句柄将被关闭,并且您将收到null。
\u Process.Kill();返回
需要WaitForExit,因为杀戮不是即时的。IOs可能会继续存在。另外,您不应该仅仅因为进程关闭了它的管道就终止它。它可能仍在做一些事情并关闭。在WaitForExit返回false之后,可能只有kill?我不明白为什么continue语句应该是一个中断。。我不断地检查这条小溪,寻找新的线路。进程B没有持续写入管道流,因此temp可以为空,也将为空。如果我中断了,那么我将很快中断循环。如果检查进程。响应是错误的想法,那么如何正确地判断进程是否已无响应并需要终止?谢谢您的建议。我更新了代码以反映它们。我仍然将pipeServer.IsConnected检查保留在while循环中,以避免抛出大多数异常。我还添加了一个检查,以确保流程仍然具有响应性。这在两个方面被打破:_process.Responding是基于GUI的,所以可能不正确。即使您需要这些语义,如果进程没有响应,也可能会丢弃缓冲数据。其次,即使pipeServer.IsConnected变为false,streamreader也可能有数据缓冲区,您将丢失这些数据<代码>如果(临时==null)继续这应该是
。。。中断。在这里,您几乎永远不会看到异常,因为大多数时候远程句柄将被关闭,并且您将收到null。
\u Process.Kill();返回
需要WaitForExit,因为杀戮不是即时的。IOs可能会继续存在。另外,您不应该仅仅因为进程关闭了它的管道就终止它。它可能仍在做一些事情并关闭。在WaitForExit返回false之后,可能只有kill?我不明白为什么continue语句应该是一个中断。。我不断地检查这条小溪,寻找新的线路。进程B没有持续写入管道流,因此temp可以为空,也将为空。如果我中断了,那么我将很快中断循环。如果检查进程。响应是错误的想法,那么如何正确判断进程是否已无响应并需要终止?