返回

异步更新文本框时解决串口通信中“I/O Operation Aborted”问题

windows

串口通信:异步更新文本框解决 "I/O Operation Aborted" 问题

问题

使用串口通信时,你可能遇到 "I/O operation has been aborted because of either a thread exit or an application request" 错误。这是因为串口通信通常需要在独立线程中进行,以避免阻塞 UI 线程。

解决方法

为了解决这个问题,你需要将委派调用移到一个新的线程中。你可以使用 ThreadPool.QueueUserWorkItem 方法在后台线程上执行委派:

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    ThreadPool.QueueUserWorkItem((_) => tWGT.BeginInvoke(new myDelegate(updateTextBox)));
}

这样,当串口数据可用时,委派调用将被排队在后台线程上执行,从而避免阻塞 UI 线程。

完整的代码示例

public delegate void myDelegate();

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{          
    ThreadPool.QueueUserWorkItem((_) => tWGT.BeginInvoke(new myDelegate(updateTextBox)));
}

public void updateTextBox()
{
    try
    {
        tWGT.AppendText(port.ReadExisting());
        tWGT.ScrollToCaret();
    }
    catch {
        port.Close();
    }
}

结论

通过将委派调用移到后台线程,你可以避免 UI 线程阻塞,并且仍然可以安全地更新文本框。

常见问题解答

  1. 为什么使用委派?

    • 委派允许你安全地在 UI 线程上更新控件,从而避免跨线程访问异常。
  2. 为什么需要在后台线程上执行委派调用?

    • 因为串口数据接收事件在 UI 线程上触发,如果委派调用也立即执行,可能会阻塞 UI 线程,从而导致 "I/O operation has been aborted" 错误。
  3. ThreadPool.QueueUserWorkItem 方法如何工作?

    • 它将委派调用排队在后台线程上执行,从而避免阻塞 UI 线程。
  4. 如何在实际代码中使用 ThreadPool.QueueUserWorkItem

    • 将委派调用传递给 ThreadPool.QueueUserWorkItem 方法,就像代码示例中那样。
  5. 还有其他方法来解决 "I/O operation has been aborted" 错误吗?

    • 是的,你可以使用同步上下文或手动线程同步来确保委派调用在正确的线程上执行。