Results 1 to 9 of 9

Thread: Listbox + Background Worker (Cross thread problem)

  1. #1

    Thread Starter
    Addicted Member HunterTTP's Avatar
    Join Date
    Jul 2012
    Posts
    146

    Question Listbox + Background Worker (Cross thread problem)

    Alright so I will try and make this as simple a possible. For this example, there is listbox1, and button3.

    There are 10 items in listbox1 (A-T).

    The user selects 1 item and then clicks Button3.

    Button3 Starts the background worker.

    BackgroundWorker3 downloads a file using My.Computer.Network.DownloadFile ("google.com/" & ItemSelection)

    ItemSelection is "Dim(ed)" in the background worker -> Dim ItemSelection = ListBox1.SelectedItem

    So what should happen is, the user selects the Item, The user clicks "go", the background worker attempts to download from (if selection was "A") google.com/A.

    But what actually happens is, I get a "cross thread" error about how I cannot reference back to ItemSelection because it is not being used on the thread is was created on.

    Example Code-

    Code:
    Imports System.IO
    Imports Shell32
    
    Public Class Form1
    
        Dim Desktop As String = My.Computer.FileSystem.SpecialDirectories.Desktop
        Dim Username As String = Environment.UserName
        Private P As Integer
    ...

    Code:
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    
            BackgroundWorker3.RunWorkerAsync()
    
        End Sub
    ...

    Code:
     Private Sub BackgroundWorker3_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker3.DoWork
    
                Dim ItemSelection = ListBox1.SelectedItem
    
                My.Computer.Network.DownloadFile("http://google.com/" & ItemSelection, Desktop)
    
        End Sub
    The Error




    Any help would be great!


    Hunter
    Last edited by HunterTTP; Feb 17th, 2013 at 09:04 AM.

  2. #2
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Listbox + Background Worker (Cross thread problem)

    Try substituting

    Dim itemText = ListBox1.Text

    for

    Dim ItemSelection = ListBox1.SelectedItem

    and ammending the rest of the code accordingly.

  3. #3

    Thread Starter
    Addicted Member HunterTTP's Avatar
    Join Date
    Jul 2012
    Posts
    146

    Re: Listbox + Background Worker (Cross thread problem)

    Quote Originally Posted by Inferrd View Post
    Try substituting

    Dim itemText = ListBox1.Text

    for

    Dim ItemSelection = ListBox1.SelectedItem

    and ammending the rest of the code accordingly.
    Don't you mean the other way around? Just clarifying.

  4. #4
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Listbox + Background Worker (Cross thread problem)

    I mean replace
    Code:
    Dim ItemSelection = ListBox1.SelectedItem
    with
    Code:
    Dim itemText = ListBox1.Text
    and then replace all subsequent occurences of ItemSelection with itemText

    And after all that, please don't tell me it doesn't work

  5. #5

    Thread Starter
    Addicted Member HunterTTP's Avatar
    Join Date
    Jul 2012
    Posts
    146

    Re: Listbox + Background Worker (Cross thread problem)

    Sorry bud, no dice.

  6. #6
    Frenzied Member IanRyder's Avatar
    Join Date
    Jan 2013
    Location
    Healing, UK
    Posts
    1,232

    Re: Listbox + Background Worker (Cross thread problem)

    Hi,

    This is a Cross Thread issue which is why things are not working and nothing to do with the properties and methods which are trying to be demonstrated in the examples given so far.

    When you implement a secondary thread you cannot directly access the UI thread (the initially started thread directly) since this will cause a Cross Thread exception.

    The way to do this correctly is to pass, as a parameter, the information you need to use in a secondary thread from the UI thread. Have a look at this example below which passes a selected ListBox value to the BackgroundWorker:-

    Code:
    Public Class Form1
    
      Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        With ListBox1.Items
          .Add("A")
          .Add("B")
          .Add("C")
        End With
      End Sub
    
      Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        If Not ListBox1.SelectedIndex = -1 Then
          BackgroundWorker1.RunWorkerAsync(ListBox1.SelectedItem.ToString)
        End If
      End Sub
    
      Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        MsgBox("Do your work here using " & e.Argument.ToString & " as a paremeter within the secondary thread")
      End Sub
    
      Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        MsgBox("Done!")
      End Sub
    End Class
    I hope that helps.

    Cheers,

    Ian

  7. #7
    Frenzied Member
    Join Date
    Jul 2011
    Location
    UK
    Posts
    1,335

    Re: Listbox + Background Worker (Cross thread problem)

    You know, I swear before you edited your code, you had
    Code:
    Dim ItemSelection = ListBox1.SelectedItem
    declared at Form level, outside the BGW's DoWork event handler.

    Of course it will give problems referencing the ListBox inside the DoWork event handler, as that runs on a thread that is not the UI's thread and so you can't access any Form's Controls in there.

    In any case, I prefer Ian's solution of passing the value as an argument rather than accessing a (disappeared) global variable

  8. #8

    Thread Starter
    Addicted Member HunterTTP's Avatar
    Join Date
    Jul 2012
    Posts
    146

    Re: Listbox + Background Worker (Cross thread problem)

    Alright so this is what I have.

    Code:
    Imports System.IO
    Imports Shell32
    
    Public Class Form1
    
        Dim Desktop As String = My.Computer.FileSystem.SpecialDirectories.Desktop
        Dim Username As String = Environment.UserName
    ...

    Code:
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    
            BackgroundWorker3.RunWorkerAsync(ListBox1.SelectedItem.ToString)
    
        End Sub
    ...

    Code:
    Private Sub BackgroundWorker3_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker3.DoWork
    
                My.Computer.Network.DownloadFile("http://google.com/" & e.Argument.ToString, Desktop)
    
        End Sub


    And that gives me some kind of "call stack" error?

  9. #9

    Thread Starter
    Addicted Member HunterTTP's Avatar
    Join Date
    Jul 2012
    Posts
    146

    Re: Listbox + Background Worker (Cross thread problem)

    Figured it out. I forgot the "If Not ListBox1.SelectedIndex = -1 Then". Thanks!

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