0

I have the following code in a form called Fetch.vb:

Imports System.ComponentModel ' might not be needed? Imports System.Threading Public Class Fetch Public Sub New() InitializeComponent() backgroundWorker1.WorkerReportsProgress = True backgroundWorker1.WorkerSupportsCancellation = True End Sub Private Sub btnFetch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFetch.Click Dim ctrl As Control For Each ctrl In Me.Controls If TypeName(ctrl) = "TextBox" Then If ctrl.Text.Length = (Not 0) Then tbList.Add(ctrl.Text) MsgBox(tbList.Item(0).ToString) Exit For End If End If Next ' ProcessLinks() btnFetch.Enabled = False BackgroundWorker1.RunWorkerAsync() End Sub Public Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork AddHandler BackgroundWorker1.DoWork, AddressOf backgroundWorker1_DoWork ProcessLinks() End Sub End Class 

Now process links is a module with a public sub in with the code I am trying to run, I don't need any arguments passed to it, and it doesn't do anything that (I think) could affect this, I think I'm just doing the threading code wrong. I have backgroundworker1 in my fetch.vb form, and when I click btn Fetch, the program does nothing.

Any help and guidance or reading material would be greatly appreciated.

EDIT Here is my LinkProcess module.

Public Module LinkProcess Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Fetch.BackgroundWorker1.DoWork ProcessLinks() End Sub Public Sub ProcessLinks() Dim tbContent As String For Each tbContent In Fetch.tbList Process.Start(tbContent) Next End Sub End Module 
2
  • 1. Off-topic advice: Instead of checking whether the BackgroundWorker.IsBusy, simply disable the btnFetch button (and enable it again once the background work is completed). From a user experience standpoint, it doesn't make sense to have an enabled button that doesn't do anything. 2. Incidentally, this might also remove a potential source of errors; namely, have you verified that .IsBusy is actually False during the first button click? Commented Jun 26, 2014 at 11:50
  • Thank you for your advice, I will do it like this straight away. Commented Jun 26, 2014 at 17:27

1 Answer 1

1

What does your ProcessLinks() method do? Is it accessing any UI elements - like setting some text in label, or adding text a TextBox, etc.? If that is the case, then that won't work. You should not access the UI elements from inside your BackgroundWorker DoWork.

Here is a small post I wrote about how to use the BackgroundWorker correctly. This might help you. http://www.vbforums.com/showthread.php?680130-Correct-way-to-use-the-BackgroundWorker

Sign up to request clarification or add additional context in comments.

4 Comments

It doesn't modify any UI elements, it just loops through the textboxes on a form and runs process.start on the contents. Thanks for the link though, will give it a read.
ok.. So I was correct. Don't access the TextBoxes from your BackgroundWorker DoWork. Put them in variables etc. before calling the RunWorkerAsync().
I stuck the contents into a list of string, and now the code will skip my backgroundworker1.dowork sub... I tried putting the backgroundworker1.dowork sub in the same module that contains the ProcessLinks sub. Now I have the Error "Handles clause requires a WithEvents variable defined in the containing type or one of its base types"
You have somehow removed the Handles clause of the DoWork function. Put that back and it should work. Public Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork