背景工作者和连续事件
Background Workers and Successive Events
我又回来了,代码比上次多了。我可能会在这里和那里引用我以前的问题,但这个问题是独立的
我设法说服我的雇主放弃了我必须使用的专有串行端口通信库,所以现在我从头开始使用 SerialPorts 和 BackgroundWorkers 以便我知道它们是如何工作的。
这是我的代码:
Imports System
Imports System.IO.Ports
Public Class Form1
'SerialPort Port and BackgroundWorker Worker declared in form
Delegate Sub AppendText_Delegate(ByVal txtBox As TextBox, ByVal str As String)
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Port.PortName = ("COM9")
Port.BaudRate = 115200
Port.Parity = Parity.None
Port.StopBits = StopBits.One
Port.Handshake = Handshake.None
Port.ReadTimeout = 1000
Port.WriteTimeout = 1000
Port.Open()
AddHandler Port.DataReceived, AddressOf DataReceived
Worker.WorkerReportsProgress = True
Worker.WorkerSupportsCancellation = True
End Sub
Private Sub btnSend_Click(sender As System.Object, e As System.EventArgs) Handles btnSend.Click
Port.Write(txtInput.Text & vbCrLf)
End Sub
Private Sub DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Worker.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles Worker.DoWork
If Worker.CancellationPending Then
e.Cancel = True
End If
AppendText_ThreadSafe(Me.txtOutput, Port.ReadLine())
End Sub
Private Sub AppendText_ThreadSafe(ByVal txtBox As TextBox, ByVal str As String)
If txtBox.InvokeRequired Then
Dim MyDelegate As New AppendText_Delegate(AddressOf AppendText_ThreadSafe)
Me.Invoke(MyDelegate, New Object() {txtBox, str})
Else
txtBox.AppendText(str)
End If
End Sub
End Class
此刻我真的不确定 DataReceived
事件和 BackgroundWorker
事件是如何协同工作的。我应该把 Worker.RunWorkerAsync()
放在哪里,以便它仅在引发 DataReceived
事件时才调用 DoWork() ?我应该将两个事件绑定到同一个方法吗?
感谢您的帮助,对于这个问题的简单性,我们深表歉意。我才刚刚开始使用 BackgroundWorkers,可以这么说,我仍在寻找自己的立足点。
DataReceived
event of the SerialPort
class 在后台线程上引发,因此它不会阻塞 UI 线程,因此您不需要使用 BackgroundWorker
在这种情况下。因为 DataReceived
是在后台线程上调用的,所以如果您需要从该处理程序更新任何 UI 控件,则需要使用 Invoke
。
我又回来了,代码比上次多了。我可能会在这里和那里引用我以前的问题,但这个问题是独立的
我设法说服我的雇主放弃了我必须使用的专有串行端口通信库,所以现在我从头开始使用 SerialPorts 和 BackgroundWorkers 以便我知道它们是如何工作的。
这是我的代码:
Imports System
Imports System.IO.Ports
Public Class Form1
'SerialPort Port and BackgroundWorker Worker declared in form
Delegate Sub AppendText_Delegate(ByVal txtBox As TextBox, ByVal str As String)
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Port.PortName = ("COM9")
Port.BaudRate = 115200
Port.Parity = Parity.None
Port.StopBits = StopBits.One
Port.Handshake = Handshake.None
Port.ReadTimeout = 1000
Port.WriteTimeout = 1000
Port.Open()
AddHandler Port.DataReceived, AddressOf DataReceived
Worker.WorkerReportsProgress = True
Worker.WorkerSupportsCancellation = True
End Sub
Private Sub btnSend_Click(sender As System.Object, e As System.EventArgs) Handles btnSend.Click
Port.Write(txtInput.Text & vbCrLf)
End Sub
Private Sub DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
Worker.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles Worker.DoWork
If Worker.CancellationPending Then
e.Cancel = True
End If
AppendText_ThreadSafe(Me.txtOutput, Port.ReadLine())
End Sub
Private Sub AppendText_ThreadSafe(ByVal txtBox As TextBox, ByVal str As String)
If txtBox.InvokeRequired Then
Dim MyDelegate As New AppendText_Delegate(AddressOf AppendText_ThreadSafe)
Me.Invoke(MyDelegate, New Object() {txtBox, str})
Else
txtBox.AppendText(str)
End If
End Sub
End Class
此刻我真的不确定 DataReceived
事件和 BackgroundWorker
事件是如何协同工作的。我应该把 Worker.RunWorkerAsync()
放在哪里,以便它仅在引发 DataReceived
事件时才调用 DoWork() ?我应该将两个事件绑定到同一个方法吗?
感谢您的帮助,对于这个问题的简单性,我们深表歉意。我才刚刚开始使用 BackgroundWorkers,可以这么说,我仍在寻找自己的立足点。
DataReceived
event of the SerialPort
class 在后台线程上引发,因此它不会阻塞 UI 线程,因此您不需要使用 BackgroundWorker
在这种情况下。因为 DataReceived
是在后台线程上调用的,所以如果您需要从该处理程序更新任何 UI 控件,则需要使用 Invoke
。