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

如何实现Go与C#控制台程序的长期管道连接

Go与C#进程间多次管道交互问题排查与修复

问题分析

你的代码存在两个关键问题导致无法实现多次交互:

  • Go端:io.WriteString(stdin, w1)未添加换行符,而C#的Console.ReadLine()需要读取到换行才会返回;同时io.ReadAll(stdout)会持续读取直到进程退出(EOF),第一次读取后会阻塞后续操作。
  • 调试符号错误:大概率是C#程序未生成调试符号(pdb文件),或附加进程时未选择正确的调试模式。

修复方案

1. 修正Go程序代码

调整输入输出逻辑,确保每行输入带换行,同时用逐行读取替代ReadAll:

package main

import (
    "bufio"
    "fmt"
    "log"
    "os/exec"
)

func main() {
    cmd := exec.Command("path/to/ConsoleApp.exe") // 替换为实际路径

    stdout, err := cmd.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }
    stdin, err := cmd.StdinPipe()
    if err != nil {
        log.Fatal(err)
    }

    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    defer cmd.Wait() // 确保进程退出时等待

    // 创建stdout的逐行读取器
    scanner := bufio.NewScanner(stdout)

    for {
        var w1 string
        _, err := fmt.Scanln(&w1)
        if err != nil {
            log.Fatal(err)
        }

        // 写入输入并添加换行符,匹配Console.ReadLine的要求
        _, err = fmt.Fprintf(stdin, "%s\n", w1)
        if err != nil {
            log.Fatal(err)
        }

        // 读取C#程序输出的一行结果
        if scanner.Scan() {
            fmt.Println("当前累加结果:", scanner.Text())
        }
        if err := scanner.Err(); err != nil {
            log.Fatal(err)
        }
    }
}

2. 优化C#程序调试与逻辑

  • 调试符号问题:确保C#项目设置为Debug模式,在生成选项中勾选"生成调试信息"(默认Debug模式已开启),编译后会生成和exe同名的pdb文件,附加进程时选择该exe即可正常调试。
  • 优化文件标记逻辑并增加控制台调试输出:
using System;
using System.IO;

namespace ConsoleApp
{
    class Program
    {
        static int Main(string[] args)
        {
            double sum = 0;
            bool flag = true;
            while (flag)
            {
                var str = Console.ReadLine();
                // 直接输出接收内容到控制台,方便调试
                Console.WriteLine($"收到输入:{str ?? "空内容"}");
                
                double addend;
                flag = double.TryParse(str, out addend);

                using (StreamWriter writer = new StreamWriter("t.txt", append: true)) // 改为追加模式,避免覆盖历史记录
                {
                    writer.WriteLine($"[{DateTime.Now}] 收到:{str},转换成功:{flag}");
                }

                sum += flag ? addend : 0;
                Console.WriteLine(sum);
            }
            return 0;
        }
    }
}

关键修复点说明

  • Go端必须添加换行符:Console.ReadLine()以换行作为输入结束标志,没有换行的话C#进程会一直等待输入。
  • 替换io.ReadAll为bufio.Scanner:ReadAll会等待进程输出EOF才返回,而我们需要的是每次交互后的单行结果,逐行读取更符合需求。
  • 移除不必要的goroutine:写入stdin不需要异步,同步写入能确保输入发送完成后再读取结果,避免时序问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:25:22