如何跨线程更新文本框以实时显示计量秤读取值?
解决WinForms跨线程更新TextBox及实时读取计量秤数据的问题
问题分析
你当前存在两个核心问题:
- 非UI线程(Socket回调线程)直接操作
textBox1触发跨线程安全错误 - 仅在点击按钮时更新一次UI,无法实时同步计量秤的最新数据
解决方案
1. 封装线程安全的UI更新方法
WinForms要求所有UI操作必须在UI线程执行,因此需要专门写一个安全更新TextBox的方法:
// 线程安全更新TextBox的工具方法 private void UpdateTextBoxSafely(string text) { if (textBox1.InvokeRequired) { // 当前非UI线程,委托UI线程执行更新 textBox1.Invoke(new Action<string>(UpdateTextBoxSafely), text); } else { // UI线程直接更新文本 textBox1.Text = text; } }
2. 修改数据接收回调,实现实时更新
在OnRecievedData方法中,删除直接赋值textBox1.Text的代码,替换为调用上面的安全更新方法:
修改OnRecievedData中的关键逻辑:
if (sRecieved.IndexOf("\n") != -1) { // 触发自定义数据接收事件 if (ReceivedData != null) ReceivedData(this._Mensagem); this._LastReadValue = this._Mensagem; // 替换直接赋值,调用安全更新方法 UpdateTextBoxSafely(this._LastReadValue); this._Mensagem = ""; }
3. 调整初始更新逻辑
原来updateGUI方法里的textBox1.Text = this._LastReadValue;可以移除,因为Socket连接成功后,后续的实时数据会通过回调自动触发UI更新。如果需要在连接成功时显示初始值,可以在OnConnect的成功分支里调用UpdateTextBoxSafely(this._LastReadValue)。
完整修改后的关键代码片段
// 新增线程安全更新方法 private void UpdateTextBoxSafely(string text) { if (textBox1.InvokeRequired) { textBox1.Invoke(new Action<string>(UpdateTextBoxSafely), text); } else { textBox1.Text = text; } } private void OnRecievedData(IAsyncResult ar) { Socket sock = (Socket)ar.AsyncState; if (m_sock.Connected == false) return; try { int nBytesRec = sock.EndReceive(ar); if (nBytesRec > 0) { string sRecieved = Encoding.ASCII.GetString(m_byBuff, 0, nBytesRec); this._Mensagem = sRecieved; if (sRecieved.IndexOf("\n") != -1) { if (ReceivedData != null) ReceivedData(this._Mensagem); this._LastReadValue = this._Mensagem; // 安全触发UI更新 UpdateTextBoxSafely(this._LastReadValue); this._Mensagem = ""; } SetupRecieveCallback(sock); } else { sock.Shutdown(SocketShutdown.Both); sock.Close(); throw new Exception($"Client {sock.RemoteEndPoint}, disconnected"); } } catch (Exception ex) { sock.Close(); } } void updateGUI() { Connect(); // 移除单次赋值,由Socket回调实时更新UI }
说明
- 线程安全方法
UpdateTextBoxSafely通过InvokeRequired判断线程环境,非UI线程时将更新操作委托给UI线程执行,彻底解决跨线程错误。 - 每次Socket收到完整的计量秤数据(以
\n结尾)时,都会自动触发UI更新,实现数据实时同步。 - 点击按钮建立连接后,Socket会持续监听计量秤数据,后续所有新数据都会自动更新到TextBox中,不再是单次更新。
内容的提问来源于stack exchange,提问作者Hugo Silva
相关产品推荐
相关产品推荐

