模块化C#WinForms应用程序中的跨线程通信



我目前正在使用多个动态加载的插件开发一个模块化应用程序。主窗口还可以作为来自各种插件的反馈消息的输出。这是一个中心需求,所以插件不能有自己的输出。

主程序由3个类组成:

  • 创建GUI并处理插件调用的主类

  • 使用MEF 从指定文件夹收集插件的第二个类

  • 导出可以从插件访问的类,以发送消息(string[](显示在主窗口中

Export类使用一个事件来接收消息,主类订阅该事件并将消息写入DataGridView。

只要我启动一个插件而不将其放入单独的线程中,这就可以很好地工作。但是不出所料,插件工作时主窗体被冻结了。现在我尝试为插件创建单独的线程,这样我就可以同时在后台运行多个线程。不幸的是,这会使消息接收到跨线程操作。

通过使用事件,我打算使它成为线程安全的,因为主窗体订阅事件并在"主线程"中处理消息。显然我错了…我仍然不太明白主窗口中的事件触发方法是如何突然切换到单独的任务中的。。。

一些附加信息:

  • 调用不是一个选项,因为输出窗口由比DataGridView多得多的控件组成,并且每当收到消息时,这些控件都会不断被修改。

  • 主窗体有一个公共静态字符串[],用于将消息的内容从导出类传输到主类

是否有任何方法可以将消息写入方法放入主线程,但仍然能够订阅从另一个线程激发的事件?或者可能有其他方法来完成任务?

[Export]
public class Exportklasse : Interfaces.IMain
{
public static event EventHandler MeldungEintragen;
// Diese Methode aufrufen, um von Modulen aus Textmeldungen einzutragen
public void MeldungEmpfangen(string[] MeldungInput, EventArgs e)
{
EventHandler EintragenEvent = MeldungEintragen;
if (EintragenEvent != null) {
MainForm.MeldungText = MeldungInput;
EintragenEvent(this, e);
}
}
}

这样的东西能用吗?:

private readonly IBackendWorker worker;
private SynchronizationContext uiContext;
public MainForm(IBackendWorker worker)
{
InitializeComponent();
this.worker = worker;
uiContext = SynchronizationContext.Current;
worker.BackendEvent += OnWorkerBackEvent;
...
}

和事件处理程序:

private void OnWorkerBackEvent(int count)
{
// schedule the action on the UI synchronisation context.
uiContext.Post((c) =>
{
// put your code to interact with UI here
outputTextBox.Text = count.ToString();
}, null);
// or: uiContext.Post((c) => outputTextBox.Text = c.ToString(), count);
}

事件处理程序在触发事件的任何线程中执行,但在UI线程中执行操作。

最新更新