gpt4 book ai didi

.net - 由于不拥有线程,串行端口读取导致错误

转载 作者:行者123 更新时间:2023-12-02 10:53:27 24 4
gpt4 key购买 nike

我有一个简单的 WPF Windows 应用程序尝试使用 System.IO.Ports.SerialPort 读取串行端口。

当我尝试读取 DataReceived 事件中的传入数据时,出现异常,提示我无权访问该线程。怎么解决?

我在 WPF 窗口类中有这个:

Public WithEvents mSerialPort As New SerialPort()
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnConnect.Click
With mSerialPort
If .IsOpen Then
.Close()
End If
.BaudRate = 4800
.PortName = SerialPort.GetPortNames()(0)
.Parity = Parity.None
.DataBits = 8
.StopBits = StopBits.One
.NewLine = vbCrLf

.Open()
End With
End Sub

Private Sub mSerialPort_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles mSerialPort.DataReceived
If e.EventType = SerialData.Chars Then
txtSerialOutput.Text += mSerialPort.ReadExisting()
End If
End Sub

Protected Overrides Sub Finalize()
If mSerialPort.IsOpen Then
mSerialPort.Close()
End If
mSerialPort.Dispose()
mSerialPort = Nothing
MyBase.Finalize()
End Sub

DataReceived 事件触发时,我在 mSerialPort.ReadExisting() 上收到以下异常:

System.InvalidOperationException was unhandled
Message="The calling thread cannot access this object because a different thread owns it."
Source="WindowsBase"
StackTrace:
at System.Windows.Threading.Dispatcher.VerifyAccess() at System.Windows.Threading.DispatcherObject.VerifyAccess() at System.Windows.DependencyObject.GetValue(DependencyProperty dp) at System.Windows.Controls.TextBox.get_Text() at Serial.Serial.mSerialPort_DataReceived(Object sender, SerialDataReceivedEventArgs e) in D:\SubVersion\VisionLite\Serial\Serial.xaml.vb:line 24 at System.IO.Ports.SerialPort.CatchReceivedEvents(Object src, SerialDataReceivedEventArgs e) at System.IO.Ports.SerialStream.EventLoopRunner.CallReceiveEvents(Object state) at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack) at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)

最佳答案

欢迎来到多线程的神奇世界!!!

发生的情况是,所有 UI 元素(类实例)只能由 UI 线程访问/更新。我不会详细介绍这个线程关联性,但它是一个重要的主题,您应该检查一下。

数据传入串行端口的事件发生在与 UI 线程不同的线程上。 UI线程有一个消息泵来处理Windows消息(如鼠标点击等)。您的串行端口不会发送 Windows 消息。当数据进入串行端口时,将使用与 UI 线程完全不同的线程来处理该消息。

因此,在您的应用程序中,mSerialPort_DataReceived 方法在与 UI 线程不同的线程中执行。您可以使用线程调试窗口来验证这一点。

当您尝试更新 UI 时,您正在尝试修改与来自不同线程的 UI 线程具有线程关联的控件,这会引发您所看到的异常。

TL;DR:您正尝试在 UI 线程之外修改 UI 元素。使用

txtSerialOutput.Dispatcher.Invoke

在 UI 线程上运行更新。 There's an example here on how to do thisin the community content of this page.

Dispatcher 将在 UI 线程上调用您的方法(它向 UI 发送一条 Windows 消息,表示“Hai guize,运行此方法 kthx”),然后您的方法可以从 UI 线程安全地更新 UI。

关于.net - 由于不拥有线程,串行端口读取导致错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1443944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com