gpt4 book ai didi

c# - 重新同步 Process.RedirectStandardOutput

转载 作者:行者123 更新时间:2023-11-30 23:27:02 25 4
gpt4 key购买 nike

背景

我正在为 node.js 应用程序编写一个 c# 包装器。在这个包装器中,我通过 Process.RedirectStandardOutput 连续读取标准输出。在类 ProcessManager 的实例中,事件绑定(bind)到函数 onOutputDataReceived。在同一个实例中,还有一个自定义事件系统的实例。

[进程管理器]

EventSystem eventSystem;

private void Start()
{
[...]

process.OutputDataReceived += onOutputDataReceived;

[...]
}

private void onOutputDataReceived(object sender, DataReceivedEventArgs e)
{
[...]

eventSystem.call(eventName, args);
}

[事件系统]

List<EventHandler> eventList;

public Boolean call(String eventName, dynamic args)
{
[...]

foreach (EventHandler handler in eventList)
{
handler(args);
}

[...]
}

问题发生在调用事件时。这是使用我的包装器的 winforms 应用程序的示例。

Wrapper.ProcessManager procMan;

procMan.eventSystem.on(eventName, (a) =>
{
button1.Text = someValue;
});

运行时,应用程序崩溃并显示消息

Cross-thread operation not valid: Control 'button1' accessed from a thread other than the thread it was created on

据我了解,我的问题是:

onOutputDataReceived 在其自己的线程中异步执行。由于同一个线程(仅用于处理输出)继续调用事件,因此我无意中对我的包装器进行了多线程处理,这让实现它的任何人的生活都变得更加困难。

基本上

我需要在维护 ProcessManager 实例其余部分的同一个线程中运行行 eventSystem.call(),一旦收到新的输出数据尽可能。关于如何实现最佳效果有什么想法吗?


一个解决方案我想到的是这样的

[进程管理器]

Queue<string> waiting = new Queue<string();
EventSystem eventSystem;

private void onOutputDataReceived(object sender, DataReceivedEventArgs e)
{
[...]
waiting.Enqueue(eventName);
}

private void WhenReady()
{
while(waiting.Count > 0)
eventSystem.call(waiting.Dequeue());
}

据我所知,这将涉及每 x 毫秒进行某种轮询,这感觉不像是一个干净的解决方案。此外,在我看来,这样的解决方案在没有收到消息时成本太高,而在收到消息时又太慢。

最佳答案

执行 nodejs 进程并读取其输出的代码不需要了解事件订阅者的线程要求。让订阅者满足自己的要求:

(a) =>
{
Invoke(new Action(() => button1.Text = someValue)); //marshal to UI thread
}

您的暂定解决方案行不通,因为它会阻塞 UI 线程。

此外,waiting 正在以不同步的方式使用...这是一个不相关的错误。

关于c# - 重新同步 Process.RedirectStandardOutput,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36670456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com