Results 1 to 4 of 4

Thread: [RESOLVED] VB.net 2005 BackGroundWorker help

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2005
    Location
    North Carolina
    Posts
    52

    Resolved [RESOLVED] VB.net 2005 BackGroundWorker help

    I am trying to write a program to read and write to a radio scanner I have via the serial port. I have the writing down (It was easy enough) and I can read the data from the scanner using the datarecieved event. I can display the read data in a messagebox with no problem but when I try to write it to a TextBox I run into a cross Threading issue. I have been reading up on the BackGroundWorker but I am having trouble wraping my head around it. A couple of questions I have is

    What should I do in the DoWork event?
    Run the Datarevieved event
    or
    the actual write to textbox event

    Also some of the syntax is confusing to me

    Here is the code, any help is appreciated (This project is just for personal learning so any coments about the code is appreciated)

    VB Code:
    1. Imports System.Text
    2. Imports System.IO.Ports
    3. Imports System.Threading
    4. Imports System.ComponentModel
    5.  
    6.  
    7. Public Class Main
    8.  
    9.     Dim WithEvents WorkingPort As New SerialPort("com1", 19200)
    10.  
    11.  
    12.     Private Function EnterCommand(ByVal Input As String) As String
    13.         'Add vbcr to the ebd of all commands because the scanner protocall requires it
    14.         Dim addVbcr As String = Input & vbCr
    15.         Return addVbcr
    16.     End Function
    17.  
    18.     Private Sub RecieveScannerData(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles WorkingPort.DataReceived
    19.         'Gets data sent by the scanner and displays it in a msgbox
    20.         ' Also calls the WriteScannerData Sub which does not work and is comented out
    21.         Dim ScannerInput As String
    22.         ScannerInput = WorkingPort.ReadExisting
    23.         MsgBox("data received: " & ScannerInput)
    24.         'WriteScannerData(ScannerInput)
    25.     End Sub
    26.  
    27.     Private Sub WriteScannerData(ByVal MyDebStr As String)
    28.         'Writes scanner data to the txtFeedback TextBox
    29.         MsgBox(" passed Value : " & MyDebStr)
    30.         txtFeedback.AppendText(MyDebStr)
    31.     End Sub
    32.  
    33.     Private Sub btnOpenPort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpenPort.Click
    34.         'Opens serialport
    35.         If WorkingPort.IsOpen = False Then
    36.             WorkingPort.Open()
    37.             btnOpenPort.Enabled = False
    38.             btnClosePort.Enabled = True
    39.             btnEnterCommand.Enabled = True
    40.         Else
    41.             MessageBox.Show("Port is all ready open")
    42.         End If
    43.         lblPortStatus.Text = WorkingPort.IsOpen
    44.     End Sub
    45.  
    46.     Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    47.  
    48.         lblPortStatus.Text = WorkingPort.IsOpen
    49.         If WorkingPort.IsOpen = False Then
    50.             btnOpenPort.Enabled = True
    51.             btnClosePort.Enabled = False
    52.             btnEnterCommand.Enabled = False
    53.         Else
    54.             btnOpenPort.Enabled = False
    55.             btnClosePort.Enabled = True
    56.         End If
    57.     End Sub
    58.  
    59.     Private Sub btnClosePort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClosePort.Click
    60.         'Closes serialport
    61.         If WorkingPort.IsOpen = True Then
    62.             WorkingPort.Close()
    63.             btnClosePort.Enabled = False
    64.             btnOpenPort.Enabled = True
    65.             btnEnterCommand.Enabled = False
    66.         Else
    67.             MessageBox.Show("Port is all ready closed")
    68.         End If
    69.         lblPortStatus.Text = WorkingPort.IsOpen
    70.     End Sub
    71.  
    72.     Private Sub btnEnterCommand_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnterCommand.Click
    73.         'Sends the command chosen from the combobox "cboCommand" the the scanner via the EnterCommand function
    74.         Dim CommandText As String = cboCommand.Text
    75.         If WorkingPort.IsOpen = False Then
    76.             MessageBox.Show("You need to open the port first")
    77.             Exit Sub
    78.         ElseIf CommandText.Length = 0 Then
    79.             MessageBox.Show("Please Choose a command to send first")
    80.         Else
    81.             WorkingPort.Write(EnterCommand(CommandText))
    82.  
    83.         End If
    84.     End Sub
    85. End Class

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: VB.net 2005 BackGroundWorker help

    You cannot access controls from threads other than the main thread, except for the Invoke, BeginInvoke, EndInvoke and CreateGraphics methods. You need to use a delegate to marshall the method call to the main thread. Here is an example of using a delegate to set the Text of a TextBox from a BackgroundWorker.
    VB Code:
    1. 'This delegate matches the signature of the SetTextBoxText method so can be used to Invoke it.
    2.     Private Delegate Sub SetTextBoxTextDelegate(ByVal text As String)
    3.  
    4.     'This method starts the background thread.
    5.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    6.         Me.BackgroundWorker1.RunWorkerAsync()
    7.     End Sub
    8.  
    9.     'This method sets the TextBox.Text property.
    10.     Private Sub SetTextBoxText(ByVal text As String)
    11.         Me.TextBox1.Text = text
    12.     End Sub
    13.  
    14.     'This method does the work of the background thread.
    15.     Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    16.         Me.Invoke(New SetTextBoxTextDelegate(AddressOf SetTextBoxText), "Greetings from the BackgroundWorker.")
    17.     End Sub
    Note that I have defined a method specifically to set the Text property of the TextBox and a matching delegate. The DoWork event handler is executed in the background thread, so it is necessary to Invoke the desired method via an instance of the delegate. Basically it is the delegate that carries the method call across the thread boundary, thus allowing it to be executed on the main thread.

  3. #3

    Thread Starter
    Member
    Join Date
    Dec 2005
    Location
    North Carolina
    Posts
    52

    Re: VB.net 2005 BackGroundWorker help

    Works like a charm here is what I ended up with, Thanx again for you time and expertise

    VB Code:
    1. Imports System.Text
    2. Imports System.IO.Ports
    3. Imports System.Threading
    4. Imports System.ComponentModel
    5.  
    6.  
    7. Public Class Main
    8.  
    9.     Dim WithEvents WorkingPort As New SerialPort("com1", 19200)
    10.     Dim ScannerInput As String
    11.  
    12.     Private Function EnterCommand(ByVal Input As String) As String
    13.         'Add vbcr to the ebd of all commands because the scanner protocall requires it
    14.         Dim addVbcr As String = Input & vbCr
    15.         Return addVbcr
    16.     End Function
    17.  
    18.     Private Sub RecieveScannerData(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles WorkingPort.DataReceived
    19.         'Gets data sent by the scanner and displays it in a msgbox
    20.         ' Also calls the WriteScannerData Sub which does not work and is comented out
    21.         ScannerInput = WorkingPort.ReadExisting
    22.         MsgBox("data received: " & ScannerInput)
    23.         backgroundWorker1.RunWorkerAsync()
    24.         'WriteScannerData(ScannerInput)
    25.     End Sub
    26.  
    27.     Private Sub WriteScannerData(ByVal MyDebStr As String)
    28.         'Writes scanner data to the txtFeedback TextBox
    29.         'MsgBox(" passed Value : " & MyDebStr)
    30.         txtFeedback.AppendText(MyDebStr)
    31.     End Sub
    32.  
    33.     Private Sub btnOpenPort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpenPort.Click
    34.         'Opens serialport
    35.         If WorkingPort.IsOpen = False Then
    36.             WorkingPort.Open()
    37.             btnOpenPort.Enabled = False
    38.             btnClosePort.Enabled = True
    39.             btnEnterCommand.Enabled = True
    40.         Else
    41.             MessageBox.Show("Port is all ready open")
    42.         End If
    43.         lblPortStatus.Text = WorkingPort.IsOpen
    44.     End Sub
    45.  
    46.     Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    47.         lblPortStatus.Text = WorkingPort.IsOpen
    48.         If WorkingPort.IsOpen = False Then
    49.             btnOpenPort.Enabled = True
    50.             btnClosePort.Enabled = False
    51.             btnEnterCommand.Enabled = False
    52.         Else
    53.             btnOpenPort.Enabled = False
    54.             btnClosePort.Enabled = True
    55.         End If
    56.  
    57.     End Sub
    58.  
    59.     Private Sub btnClosePort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClosePort.Click
    60.         'Closes serialport
    61.         If WorkingPort.IsOpen = True Then
    62.             WorkingPort.Close()
    63.             btnClosePort.Enabled = False
    64.             btnOpenPort.Enabled = True
    65.             btnEnterCommand.Enabled = False
    66.         Else
    67.             MessageBox.Show("Port is all ready closed")
    68.         End If
    69.         lblPortStatus.Text = WorkingPort.IsOpen
    70.     End Sub
    71.  
    72.     Private Sub btnEnterCommand_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnterCommand.Click
    73.         'Sends the command chosen from the combobox "cboCommand" the the scanner via the EnterCommand function
    74.         Dim CommandText As String = cboCommand.Text
    75.         If WorkingPort.IsOpen = False Then
    76.             MessageBox.Show("You need to open the port first")
    77.             Exit Sub
    78.         ElseIf CommandText.Length = 0 Then
    79.             MessageBox.Show("Please Choose a command to send first")
    80.         Else
    81.             WorkingPort.Write(EnterCommand(CommandText))
    82.         End If
    83.     End Sub
    84.  
    85.     Private Delegate Sub SetTextBoxTextDelegate(ByVal text As String)
    86.  
    87.     Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles backgroundWorker1.DoWork
    88.         Me.Invoke(New SetTextBoxTextDelegate(AddressOf WriteScannerData), ScannerInput)
    89.     End Sub
    90. End Class

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: [RESOLVED] VB.net 2005 BackGroundWorker help

    I would just recommend that you rename "SetTextBoxTextDelegate" to "WriteScannerDataDelegate", just so that the intended link between the two is obvious. You might not use such similar names if you wanted to use the same delegate to invoke several methods, but if there is a 1:1 correspondence then it is appropriate. Note also that if you ever need to do invoke a method that takes no arguments you don't have to declare your own delegate. You can simply use an instance of the MethodInvoker delegate.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width