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

仅在事件内调用事件触发方法时出现跨线程操作错误求助

解决SerialPort DataReceived事件中跨线程访问WinForms控件的异常

问题原因

SerialPort的DataReceived事件是在后台线程中触发的,而WinForms控件(比如LogTextBox)只能由创建它的UI线程访问和修改,跨线程操作必然抛出System.InvalidOperationException。而DoAThing方法因为用了await,后续代码会自动回到UI线程执行,所以日志能正常写入。

解决方案

以下是几种实用的解决方式,按需选择:

方法1:在日志事件处理中直接判断并切换线程

修改主窗体中的事件处理代码,通过Invoke切换到UI线程操作控件:

Libby.Log += (sender, e) =>
{
    // 检查是否需要跨线程调用
    if (LogTextBox.InvokeRequired)
    {
        // 委托给UI线程执行操作
        LogTextBox.Invoke(new Action(() =>
        {
            LogTextBox.AppendText($@"{DateTime.Now:hh\:mm\:ss\.ffff}: {e.Message}{Environment.NewLine}");
        }));
    }
    else
    {
        // 已在UI线程,直接操作
        LogTextBox.AppendText($@"{DateTime.Now:hh\:mm\:ss\.ffff}: {e.Message}{Environment.NewLine}");
    }
};

方法2:封装通用UI线程操作方法

在窗体类中封装一个通用方法,简化重复代码:

// 窗体类内新增方法
private void RunOnUiThread(Action action)
{
    if (InvokeRequired)
    {
        Invoke(action);
    }
    else
    {
        action();
    }
}

然后日志事件处理可以简化为:

Libby.Log += (sender, e) =>
{
    RunOnUiThread(() => 
    {
        LogTextBox.AppendText($@"{DateTime.Now:hh\:mm\:ss\.ffff}: {e.Message}{Environment.NewLine}");
    });
};

方法3:在类库中统一切换到UI线程触发事件(可选)

如果不想在窗体端处理跨线程逻辑,可以在类库中捕获UI线程上下文,确保日志事件在UI线程触发:
修改类库代码:

public class LibraryWithLoggingFunctionInIt
{
    SerialPort Port = new SerialPort(/* Port Parameters */);
    private readonly SynchronizationContext _uiSyncContext;
    
    public LibraryWithLoggingFunctionInIt()
    {
        // 捕获创建实例时的线程上下文(需确保实例在UI线程创建,比如窗体构造函数中)
        _uiSyncContext = SynchronizationContext.Current ?? new SynchronizationContext();
        Port.DataReceived += Port_DataReceived;
    }

    // 其他方法保持不变...

    public void Logger(string message)
    {
        // 在UI线程上下文触发日志事件
        _uiSyncContext.Post(_ => Log?.Invoke(this, new LoggerMessageArgs(message)), null);
    }
}

这种方式下,窗体端的日志事件处理可以保持原样,无需额外判断线程。

验证

修改完成后,当SerialPort触发DataReceived事件时,日志会通过UI线程写入LogTextBox,不会再抛出异常,能正常记录"I received new data!"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 20:35:56