|
-
Feb 17th, 2013, 07:44 AM
#1
Thread Starter
Addicted Member
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.
-
Feb 17th, 2013, 08:02 AM
#2
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.
-
Feb 17th, 2013, 08:37 AM
#3
Thread Starter
Addicted Member
Re: Listbox + Background Worker (Cross thread problem)
 Originally Posted by Inferrd
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.
-
Feb 17th, 2013, 08:43 AM
#4
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
-
Feb 17th, 2013, 09:04 AM
#5
Thread Starter
Addicted Member
Re: Listbox + Background Worker (Cross thread problem)
-
Feb 17th, 2013, 09:08 AM
#6
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
-
Feb 17th, 2013, 09:19 AM
#7
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
-
Feb 17th, 2013, 09:20 AM
#8
Thread Starter
Addicted Member
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?
-
Feb 17th, 2013, 09:23 AM
#9
Thread Starter
Addicted Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|