为什么我的事件处理程序在我从另一个进程的标准输出读取时不触发

本文关键字:读取 标准输出 进程 另一个 事件处理 我的 程序 为什么 | 更新日期: 2023-09-27 18:34:56

我有一个非常简单的C#项目,它有一个UI进程和一个工作进程。工作线程代码需要是一个进程(而不是线程(,因为它可以由 UI 或 Windows 任务计划程序运行。

在 UI 代码中,我将ProcessStartInfo.RedirectStandardOutput设置为 true 并注册事件处理程序。然后,我开始该过程(使用 Process.Start() 并调用 Process.BeginOutputReadline() .但是,我指定为 OutputDataReceived 事件处理程序的方法永远不会触发。当我在不重定向其标准输出的情况下运行工作进程时,我在控制台上看到了预期的输出。当我打开输出重定向时,我在控制台上看不到任何内容(如预期的那样(,但事件处理程序也不会触发。我还需要从另一个进程的标准输出流中异步读取其他内容吗?

编辑:我已经设法用两个简单的控制台进程复制了这个问题。

首先是父级:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace OutputRedirectionEventHandlerTest
{
    class ParentProgram
    {
        static void Main(string[] args)
        {
            ProcessStartInfo processInfo = new ProcessStartInfo()
            {
                FileName = "OutputRedirectionWorker.exe",
                RedirectStandardOutput = true,
                UseShellExecute = false
            };
            Process subProcess = new Process()
            {
                StartInfo = processInfo
            };
            subProcess.OutputDataReceived += 
                new DataReceivedEventHandler(OutputHandler);
            subProcess.Start();
            subProcess.BeginOutputReadLine();

        }
        static void OutputHandler(object SendingProcess, 
            DataReceivedEventArgs args)
        {
            Console.Out.WriteLine("Received from subprocess: " + args.Data);
        }
    }
}

然后,孩子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
namespace OutputRedirectionWorker
{
    class ChildProgram
    {
        static void Main(string[] args)
        {
            Console.Out.WriteLine("Output1");
            Console.Out.WriteLine("Output2");
            Console.Out.WriteLine("Output3");
            Thread.Sleep(10000);
        }
    }
}

父级永远不会打印任何输出。

为什么我的事件处理程序在我从另一个进程的标准输出读取时不触发

您需要了解对BeginOutputReadLine的调用会立即返回。 它启动标准输出的异步读取。

您提供的示例中的问题是父程序在调用 BeginOutputReadLine 后立即退出。 它从来没有机会读取输出 - 它在子程序启动之前退出。 您需要使用某种循环保持父级运行,以便它读取标准输出。

尝试这样的事情:

static void Main(string[] args)
    {
        ProcessStartInfo processInfo = new ProcessStartInfo()
        {
            FileName = "OutputRedirectionWorker.exe",
            RedirectStandardOutput = true,
            UseShellExecute = false
        };
        Process subProcess = new Process()
        {
            StartInfo = processInfo
        };
        subProcess.OutputDataReceived += 
            new DataReceivedEventHandler(OutputHandler);
        subProcess.Start();
        subProcess.BeginOutputReadLine();
        while (Console.ReadLine().ToLower() != "quit") {
            // looping here waiting for the user to type quit
        }
    }