C# 异步读取输出时,外部进程阻塞主线程

C# 异步读取输出时,外部进程阻塞主线程,c#,wpf,multithreading,asynchronous,C#,Wpf,Multithreading,Asynchronous,因此,我的WPF应用程序中有以下代码 ghci = new Process { StartInfo = new ProcessStartInfo("ghci") { WorkingDirectory = System.IO.Path.GetDirectoryName(path), Arguments = System.IO.Path.GetFileNam

因此,我的WPF应用程序中有以下代码

        ghci = new Process
        {
            StartInfo = new ProcessStartInfo("ghci")
            {
                WorkingDirectory = System.IO.Path.GetDirectoryName(path),
                Arguments = System.IO.Path.GetFileName(path),
                RedirectStandardOutput = true,
                RedirectStandardInput = true,
                UseShellExecute = false,
                CreateNoWindow = true
            }
        };
        ghci.OutputDataReceived += (obj, data) =>
        {
            this.Dispatcher.InvokeAsync(() =>
            {
                ghciOutput.AppendText(data.Data + "\n");
                ghciOutput.Focus();
                ghciOutput.CaretIndex = ghciOutput.Text.Length;
                ghciOutput.ScrollToEnd();
                ghciInput.Focus();
                Keyboard.Focus(ghciInput);
            });
        };
        ghci.Start();
        ghci.BeginOutputReadLine();
但是,当进程开始输出大量数据时,该输出中的每一行都会很快触发事件,整个应用程序都会冻结。为什么会这样?我想我已经确保了这一点,首先执行异步的BeginOutputReadLine(尽管我很可能不知道这到底意味着什么),然后在事件中执行InvokeAsync,以确保主线程在有时间时更新输出


我还应该注意,当应用程序冻结时,输出文本框不会更新新数据,尽管这可能只是应用程序冻结的结果。

您需要将传入数据缓冲在tje
OutputDataReceived
缓冲区中,并通过
InvokeAsync
将其分块(每隔2-3秒)发送到UI,在任何情况下都比你现在更频繁

您可以缓冲到
字符串中,并且可以每隔100行左右分派一次(以避免测量时间)。不要忘记在分派后清除字符串,或者只使用另一个实例,让旧实例被收集

目前,您正在通过UI更新终止UI线程


我想这很清楚。如果你需要一个例子,让我知道,我会看看我能做些什么。

我目前找到的更好的解决方案是将InvokeAsync优先级设置为ApplicationIdle。但我认为我最终会选择您的解决方案,因为当前调度程序充满了事件,我无法阻止它在进程运行时输出旧数据finishes@LukaHorvat:是的。如果更新之间的时间间隔很长,就会发生这种情况。如果您可以不使用旧数据更新UI(即监控实时传感器),则可以使用
ApplicationIdle
dispatch priority。