简体   繁体   English

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

[英]Why don't my event handlers fire when I'm reading from the standard output of another process

I have a very simple C# project that has a UI process and a worker process. 我有一个非常简单的C#项目,具有一个UI进程和一个辅助进程。 The worker code needs to be a process (rather than a thread) because it can be run by either the UI or by the Windows Task Scheduler. 辅助代码需要是一个进程(而不是线程),因为它可以由UI或Windows Task Scheduler运行。

In the UI code, I set the ProcessStartInfo.RedirectStandardOutput to true and I register the event handlers. 在UI代码中,我将ProcessStartInfo.RedirectStandardOutput设置为true并注册了事件处理程序。 Then, I start the process (with Process.Start() and call Process.BeginOutputReadline() . Yet, the method that I have designated as the OutputDataReceived event handler never fires. When I run the worker process without redirecting it's standard output, I see the expected output on the console. When I turn on output redirection, I don't see anything on the console (as expected), but the event handlers don't fire either. Is there something else that I need to to read asynchronously from another process' standard output stream? 然后,我启动进程(使用Process.Start()并调用Process.BeginOutputReadline() 。但是,我指定为OutputDataReceived事件处理程序的方法永远不会触发。当我运行工作进程而不重定向其标准输出时,我在控制台上看到预期的输出。当我打开输出重定向时,在控制台上没有看到任何东西(如预期的那样),但是事件处理程序也没有触发。是否还需要异步读取其他内容从另一个过程的标准输出流?

EDIT: I've managed to replicate the problem with two simple console processes. 编辑:我已经设法通过两个简单的控制台过程来复制问题。

First the parent: 首先是父母:

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);
        }

    }
}

And then, the child: 然后,孩子:

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);
        }

    }
}

No output ever gets printed by the parent. 父级不会输出任何输出。

You need to understand that the call to BeginOutputReadLine returns immediately . 你需要了解的是,呼叫BeginOutputReadLine 立即返回。 It kicks off an asynchronous read of standard output. 它开始对标准输出进行异步读取。

The problem in the example that you provided is that the Parent program exits immediately after calling BeginOutputReadLine . 您提供的示例中的问题是,父程序在调用BeginOutputReadLine之后立即退出。 It never has a chance to read the output- it is exiting before the ChildProgram even starts. 它永远没有机会读取输出-它在ChildProgram甚至开始之前就已退出。 You need to keep the parent running using a loop of some kind in order for it to read the standard output. 您需要使用某种循环来保持父级运行,以便其读取标准输出。

Try something like this: 尝试这样的事情:

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
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的DragDrop处理程序不会触发? - Why won't my DragDrop handlers fire? 当我具有触摸事件处理程序时,为什么我的鼠标事件处理程序不起作用? - Why my Mouse Event Handlers are not working when I have Touch Event Handlers? 读取过程的标准输出,始终为空 - Reading standard output from process, always empty 在另一个过程中发生火灾 - Fire event in another process 为什么我的事件无法在服务中触发? - Why my events don't fire in a service? 当我单击ListView的ImageButton时为什么不触发回发事件? - Why don't I get my postback event fired when I click on the ImageButton of my ListView? 为什么我无法通过页面标记为用户控件的事件添加事件处理程序 - why i can't add event handlers for events of my usercontrol though page markup 当我用其他方法更改控件时,为什么不更新控件? - Why don't my controls update when I change them in another method? 在组合上设置DataSource时不要触发SelectedIndexChanged事件 - Don't fire the SelectedIndexChanged event when setting the DataSource on a combo 在我的C#嗅探器中设置套接字选项时,不知道为什么我收到错误代码10022(无效参数) - Don't know why I'm getting Error Code 10022 (Invalid Argument) when setting socket options in my C# sniffer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM