C# UDP服务端跨线程更新ListBox报错:无法从其他线程添加列表项
C# 跨线程更新WinForm ListBox控件的解决方案
错误原因
WinForm框架的所有UI控件都被限制为仅可在创建该控件的UI线程中操作,你在后台线程bufferHandlerThread中直接修改dataList控件的内容,属于非法跨线程操作,因此抛出cross-thread operation not valid异常。
修复方案
在需要更新UI的位置,通过控件的Invoke方法将操作调度到UI线程执行即可,修改后的完整代码如下:
public partial class Form1 : Form { public Form1() { InitializeComponent(); // 可选:调试阶段可以关闭跨线程访问校验,不推荐生产环境使用 // CheckForIllegalCrossThreadCalls = false; } private void Form1_Load(object sender, EventArgs e) { Thread serverListen = new Thread(bufferHandlerThread); // 设置为后台线程,避免窗体关闭后线程还在运行阻止进程退出 serverListen.IsBackground = true; serverListen.Start(); } private void bufferHandlerThread() { UdpClient server = new UdpClient(6661); while (true) { IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); byte[] buffer = server.Receive(ref RemoteIpEndPoint); string receivedData = Encoding.UTF8.GetString(buffer); string toAdd = RemoteIpEndPoint.Address.ToString() + " <-> " + receivedData; // 新增:将UI操作调度到UI线程执行 if (dataList.InvokeRequired) { dataList.Invoke(new Action(() => { dataList.Items.Add(toAdd); })); } else { dataList.Items.Add(toAdd); } } } }
补充说明
InvokeRequired属性用于判断当前代码是否运行在非UI线程,返回true则说明需要调度到UI线程执行操作- 给监听线程设置
IsBackground = true,可以避免窗体关闭后后台线程还继续运行,导致进程无法正常退出 - 不推荐直接设置
CheckForIllegalCrossThreadCalls = false绕过校验,该操作会隐藏线程安全风险,仅可用于临时调试
内容的提问来源于stack exchange,提问作者mesut
相关产品推荐
相关产品推荐

