在Task中重定向流程标准输入

本文关键字:标准输入 重定向 Task | 更新日期: 2023-09-27 18:17:10

我试图在一个单独的线程中启动c# (Java.exe运行jar文件)的进程,并将其重定向为standardput, StandardError和StandardOutput。

我已经成功地重定向了StandardError和StandardOutput,但是我对standardput有问题。我这样开始这个过程:

Action<object> MyAction = (object obj) =>
{
    MyProcess.Start();
    MyProcess.WaitForExit();
};
Task MyTask = new Task(MyAction);
MyTask.Start();

我需要的是能够,在我的windows窗体应用程序中,有一个文本框和一个按钮,在那里我可以输入命令,将被发送到进程standdinput,但我找不到一种方法来重定向它"任务外",从我知道它需要一个streamWriter,但我找不到一种方法来写它,当它在一个单独的线程中运行。

在Task中重定向流程标准输入

您可以在将StandardInputStandardOutput传递给Task之前获得它们:

public partial class Form1
{
    private StreamWriter _streamWriter;
    private StreamReader _streamReader;
    public Form1()
    {
        InitializeComponent();
    }
    public void InitializeProcess(object sender, EventArgs args)
    {
        var processStartInfo = new ProcessStartInfo
        {
           UseShellExecute = false,
           ErrorDialog = false, 
           RedirectStandardError = true,
           RedirectStandardInput = true, 
           RedirectStandardOutput = true                 
        }
        var myProcess = new Process(processStartInfo);
        Task.Run(() => 
        {
            MyProcess.Start();
            MyProcess.WaitForExit();
        });
        _streamWriter = MyProcess.StandardInput;
        _streamReader = MyProcess.StandardOutput;
    }
    public void ButtonEventHandler(object sender, EventArgs e)
    {
        _streamWriter.Writer( /* write stuff here */ )  
    }
}

这样,只要进程存在,您就可以访问它的流。注意,您必须添加一个检查以确保进程仍然活动,并最终处置您的StreamWriterStreamReader

编辑

我们可以注册到异步的Process.Exited事件,而不是使用线程池线程来阻塞等待WaitForExit:

    public void InitializeProcess(object sender, EventArgs args)
    {
        var processStartInfo = new ProcessStartInfo
        {
           UseShellExecute = false,
           ErrorDialog = false, 
           RedirectStandardError = true,
           RedirectStandardInput = true, 
           RedirectStandardOutput = true,
        }
        var myProcess = new Process(processStartInfo);
        myProcess.EnableRaisingEvents = true;
        myProcess.Exited += (s, e) => 
        { 
            // Do whatever you want when process ends, like 
            // Disposing of the streams.
        }
        myProcess.Start();
        _streamWriter = MyProcess.StandardInput;
        _streamReader = MyProcess.StandardOutput;
        myProcess.Start();
    }

我不认为让StandardInput跨(并行)任务访问是很容易的。两个同时访问StandardInput的并行任务中,哪一个应该得到它的输入?

我确实认为你需要一些缓冲区和/或流的编程。

另外,您确定要发送到StandardInput过程吗?它通常是只读的。(虽然它可以是一些其他任务/进程的标准输出)