You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#应用1中实时读取C#控制台应用2的周期性标准输出?

实时读取控制台应用输出的解决方案

核心问题分析

原来的代码依赖StandardOutput.ReadToEnd()和WaitForExit(),这两个方法都会阻塞直到应用2完全退出,自然无法实时捕获周期性输出。要实现实时读取,必须改为异步监听进程的输出事件,而非等待进程结束后一次性获取数据。

应用1修改方案(实时读取版本)

通过绑定Process.OutputDataReceived事件异步捕获每一行输出,同时添加超时控制确保20秒后自动终止进程并清理资源。示例代码如下:

private Process Process_app2;
private CancellationTokenSource _cts; // 用于控制20秒运行时长

public async Task Read_Std_Output_Realtime()
{
    _cts = new CancellationTokenSource();
    Process_app2 = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = app2_path,
            Arguments = arguments,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            CreateNoWindow = true,
            StandardOutputEncoding = Encoding.UTF8 // 统一编码避免乱码
        }
    };

    // 绑定输出接收事件,实时处理每一行数据
    Process_app2.OutputDataReceived += (sender, e) =>
    {
        if (!string.IsNullOrEmpty(e.Data))
        {
            // 这里替换成你的业务逻辑,比如更新UI、存储数值等
            Console.WriteLine($"实时收到:{e.Data}");
            item_value = e.Data;
        }
    };

    Process_app2.Start();
    Process_app2.BeginOutputReadLine(); // 启动异步读取循环

    // 等待20秒后终止进程
    try
    {
        await Task.Delay(TimeSpan.FromSeconds(20), _cts.Token);
    }
    catch (TaskCanceledException)
    {
        // 正常取消,无需额外处理
    }
    finally
    {
        // 停止监听并清理资源
        Process_app2.CancelOutputRead();
        if (!Process_app2.HasExited)
        {
            Process_app2.Kill();
            Process_app2.WaitForExit();
        }
        Process_app2.Dispose();
        _cts.Dispose();
    }
}

关键改动说明

  • 用OutputDataReceived事件替代ReadToEnd(),实现异步实时捕获输出
  • 调用BeginOutputReadLine()启动持续的异步读取循环
  • 新增CancellationTokenSource控制20秒运行时长,到点后自动终止应用2
  • 指定StandardOutputEncoding确保和应用2的输出编码一致,避免乱码

应用2优化建议

原代码中的Console.Clear()会输出控制字符(如ESC清屏指令),这些字符会被应用1读取到,导致无效数据。建议移除该方法,并添加循环次数限制确保进程运行20秒后自动退出:

static void Main(string[] args)
{    
    int runCount = 0;
    // 限制运行20次(每秒1次)
    while (runCount < 20)
    {
        // 替换成你的数值生成逻辑
        var item_value_output = new Random().Next(1, 100);
        Console.WriteLine(item_value_output);
        Console.Out.Flush(); // 强制刷新输出缓冲区,确保数据立即发送
        System.Threading.Thread.Sleep(1000);
        runCount++;
    }
}

应用2关键优化

  • 移除Console.Clear(),避免输出无效控制字符
  • 添加循环次数限制,确保进程运行20秒后自动退出
  • 调用Console.Out.Flush()强制刷新缓冲区,减少输出延迟

注意事项

  • 如果应用1是UI程序(WPF/WinForms),更新UI时需要切换到UI线程(如用Dispatcher.Invoke或Control.Invoke)
  • 务必在使用完Process和CancellationTokenSource后调用Dispose(),避免内存泄漏
  • 确保应用1和应用2使用相同的输出编码,防止乱码问题

内容的提问来源于stack exchange,提问作者Mdarende

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 16:00:34