0

我又回来了,代码比上次更多。我可以参考我以前的问题,但这个问题是独立的,但这个问题是独立的后台工作人员和连续活动

我设法说服我的雇主放弃专用串口通信库,我做了使用,所以现在我从头开始用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开始,现在我仍然在寻找自己的立足点,可以这么说。

+1

我没有使用它们,但我想''SerialPort'类和['DataReceived'](https://msdn.microsoft.com/en-us/library/system.io.ports。 serialport.datareceived%28v = vs.110%29.aspx)事件你不需要'BackgroundWorker',因为'DataReceived'是在后台线程上调用的。您将需要使用'Invoke'来更新'DataReceived'中的任何UI控件。 – Mark

+0

@Mark你说得对!你的直觉比我的好。添加If InvokeRequired ...语句处理所有事情。谢谢!如果你想获得积分,我会很乐意挑选你的答案。 – Django

+0

是这个问题旨在取代“其他”串行库或如何包装它,并将其用作一些新事件的基础。 “其他”lib做什么,你可以用NET的东西来取代它? – Plutonix

回答

2

SerialPort类的DataReceived事件在后台线程上引发,因此它不会阻塞UI线程,因此在这种情况下您不需要使用BackgroundWorker。因为在后台线程上调用了DataReceived,所以如果需要更新该处理程序的任何UI控件,则需要使用Invoke