Results 1 to 29 of 29

Thread: Adding a For statement into a Backgroundworker

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Question Adding a For statement into a Backgroundworker

    Alright everyone, I have fixed the Invalid URI problem by using Uri.TryCreate

    Code:
    If Uri.TryCreate(Website, UriKind.Absolute, websiteUri) Then
                        wc.DownloadStringAsync(New Uri(Website))
                    Else
                            Me.TrashSite_list.Items.Add(Website)
                        End If
    And I have also fixed the Not Responding error, just a little bit, by adding
    Code:
     T = New Thread(New ThreadStart(AddressOf Fetch))
                    T.Start()
                    CheckForIllegalCrossThreadCalls = False
    Everyone is telling me this is a really bad way to do it and implanting my code into a background worker will make my program work much better. However, I have tried and tried, searched and searched, and even asked but nobody is willing to provide me with an example for what I need. What I need is to add a Background worker for the following code:

    #Region "Leech Proxies"
    Dim T As New System.Threading.Thread(AddressOf Fetch)
    'Leech Button
    Private Sub btnLeech_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Leech_btn.Click
    If Mini.Checked = False Then
    If Website_list.Items.Count > 0 Then
    T = New Thread(New ThreadStart(AddressOf Fetch))
    T.Start()
    CheckForIllegalCrossThreadCalls = False
    Checker.Enabled = False
    Home.Enabled = False
    End If
    Else
    If Website_list.Items.Count > 0 Then
    Proxies.Show()
    Me.WindowState = FormWindowState.Minimized
    Me.Visible = False
    T = New Thread(New ThreadStart(AddressOf Fetch))
    T.Start()
    CheckForIllegalCrossThreadCalls = False
    End If
    End If
    End Sub

    'Open a bunch of new threads to download sources of webpages
    Private Sub Fetch()
    Dim Website As String
    Dim websiteUri As Uri = Nothing

    For I As Integer = 0 To Website_list.Items.Count - 1
    SyncLock Me.Website_list.Items
    Website = Me.Website_list.Items.Item(I)
    End SyncLock
    Using wc As Net.WebClient = New Net.WebClient
    AddHandler wc.DownloadStringCompleted, AddressOf SourceDownloaded
    If Uri.TryCreate(Website, UriKind.Absolute, websiteUri) Then
    wc.DownloadStringAsync(New Uri(Website))
    Else
    If Notify.Checked = True Then
    TrayIcon.ShowBalloonTip(1, "Invalid website", "There was a invalid site in the list." & Website.ToString, ToolTipIcon.Error)
    Me.TrashSite_list.Items.Add(Website)
    Else
    Me.TrashSite_list.Items.Add(Website)
    End If
    End If
    End Using
    Next

    End Sub

    'Grab the proxies from the webpages
    Private Sub SourceDownloaded(ByVal sender As Object, ByVal e As Net.DownloadStringCompletedEventArgs)
    Dim strRegex As String = "\b(??:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\:[0-9]{1,5}\b"
    Dim myRegexOptions As RegexOptions = RegexOptions.None
    Dim myRegex As New Regex(strRegex, myRegexOptions)
    Dim frm As New Proxies
    My.Settings.Proxies = New StringCollection
    If e.Error Is Nothing Then
    For Each myMatch As Match In myRegex.Matches(e.Result)
    If myMatch.Success Then
    Try
    Proxy2_list.Items.Add(myMatch.ToString)
    Proxy_list.Items.Add(myMatch.ToString)
    Proxy2_lbl.Text = "Proxies: " & Proxy2_list.Items.Count
    Proxy_lbl.Text = "Proxies: " & Proxy2_list.Items.Count
    My.Settings.Proxies.Add(myMatch.ToString)
    Catch ex As WebException
    MessageBox.Show(
    ex.ToString,
    ErrorToString,
    Windows.Forms.MessageBoxButtons.OK)
    End Try
    End If
    Next
    End If

    End Sub

    #End Region
    If anyone is willing to possibly MSN or TeamViewer with me to help me solve my problem, shoot me a PM.
    If you want to solve it on your own, then here is the full source: http://tny.cz/f0c1717f
    If you want to post an example of what I need to do, please do so!
    Last edited by Bizzet; Oct 29th, 2012 at 06:32 PM. Reason: Update

  2. #2
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    Re: Invalid URI & "Not Responding" fix

    Well actually getting an error is considered a huge leap in evolution of programming languages. Before that time stuff just stopped responding. Or finished anyway and the user never knew if the result was reliable.

    So you get an error, use a Try...Catch around that block of code and handle it by going to the next loop iteration. Also add the bad url to a listbox or something so it can be checked manually later or removed from the list whatever.
    VB 2005, Win Xp Pro sp2

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Invalid URI & "Not Responding" fix

    Quote Originally Posted by Half View Post
    Well actually getting an error is considered a huge leap in evolution of programming languages. Before that time stuff just stopped responding. Or finished anyway and the user never knew if the result was reliable.

    So you get an error, use a Try...Catch around that block of code and handle it by going to the next loop iteration. Also add the bad url to a listbox or something so it can be checked manually later or removed from the list whatever.
    Yeah, that exactly what I said I wanted to do.
    I just don't know how.
    That's why I asked..

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

    Re: Invalid URI & "Not Responding" fix

    Your mistake appears to be that you have the loop inside the Try block rather than the other way around. When an exception is thrown inside a Try block, execution immediately jumps to the Catch block, which means out of your loop. If you want to proceed with the next iteration when an exception is thrown then you need not to exit the loop, which means Try...Catch inside the loop.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  5. #5

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Invalid URI & "Not Responding" fix

    Quote Originally Posted by jmcilhinney View Post
    Your mistake appears to be that you have the loop inside the Try block rather than the other way around. When an exception is thrown inside a Try block, execution immediately jumps to the Catch block, which means out of your loop. If you want to proceed with the next iteration when an exception is thrown then you need not to exit the loop, which means Try...Catch inside the loop.
    Yes this has worked!

    Now do you have a solution to the "Not Responding" error when checking a long list of sites? Someone has mentioned Background workers will do what I need them to but I can't find a way to incorporate them into my code.

  6. #6
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Invalid URI & "Not Responding" fix

    Each thread can only do one thing at a time and if you perform a long-running task on the UI thread then it is too busy to maintain the UI, i.e. respond to user input and repaint your form and controls. The solution is to perform your long-running task on a secondary thread, freeing up the UI thread to maintain the UI.

    Using a BackgroundWorker is one way to achieve that and often the simplest way in a WinForms app. You simply call RunWorkerAsync and handle the DoWork event. DoWork is raised on a secondary thread so the DoWork event handler is executed on a secondary thread. You perform your long-running task in the DoWork event handler and the UI will not freeze up.

    The catch is that you cannot update the UI directly from a background thread, so you cannot access the form or its controls directly in the DoWork event handler. If you need to update the UI during the long-running task then you need to call ReportProgress and handle the ProgressChanged event. If you need to update the UI after the task has completed then you handle the RunWorkerCompleted event. Both events are raised on the same thread on which you called RunWorkerAsync, i.e. the UI thread, so you can access your form and its controls directly in those event handlers.

    For some examples, follow the CodeBank link in my signature and check out my thread on Using The BackgroundWorker. To implement it in your case, you should start by moving your long-running task into its own method. Once you've got that working, add your BackgroundWorker and, instead of calling the aforementioned method, call RunWorkerAsync and move the contents of your method into the DoWork event handler. You then need to look for places in that code where you're accessing the UI directly and reimplement them using the appropriate combination of ReportProgress, ProgressChanged and RunWorkerCompleted.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Invalid URI & "Not Responding" fix

    Quote Originally Posted by jmcilhinney View Post
    Each thread can only do one thing at a time and if you perform a long-running task on the UI thread then it is too busy to maintain the UI, i.e. respond to user input and repaint your form and controls. The solution is to perform your long-running task on a secondary thread, freeing up the UI thread to maintain the UI.

    Using a BackgroundWorker is one way to achieve that and often the simplest way in a WinForms app. You simply call RunWorkerAsync and handle the DoWork event. DoWork is raised on a secondary thread so the DoWork event handler is executed on a secondary thread. You perform your long-running task in the DoWork event handler and the UI will not freeze up.

    The catch is that you cannot update the UI directly from a background thread, so you cannot access the form or its controls directly in the DoWork event handler. If you need to update the UI during the long-running task then you need to call ReportProgress and handle the ProgressChanged event. If you need to update the UI after the task has completed then you handle the RunWorkerCompleted event. Both events are raised on the same thread on which you called RunWorkerAsync, i.e. the UI thread, so you can access your form and its controls directly in those event handlers.

    For some examples, follow the CodeBank link in my signature and check out my thread on Using The BackgroundWorker. To implement it in your case, you should start by moving your long-running task into its own method. Once you've got that working, add your BackgroundWorker and, instead of calling the aforementioned method, call RunWorkerAsync and move the contents of your method into the DoWork event handler. You then need to look for places in that code where you're accessing the UI directly and reimplement them using the appropriate combination of ReportProgress, ProgressChanged and RunWorkerCompleted.
    I have been doing lots of reading on background worker but I couldn't find anything about the 'For' statement and BackgroundWorker.

    If I add my code to a Background worker, it is playing two loops in one.

    This is messing it up:
    Code:
    For I As Integer = 0 To lisaWebsites.Items.Count - 1
    How do I add this statement to a Background worker?

  8. #8
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Invalid URI & "Not Responding" fix

    As I have said in this thread and demonstrated in my CodeBank thread, you cannot access controls directly in the DoWork event handler. That means that any data you need from the UI in the DoWork event handler has to be gathered up before you call RunWorkerAsync and then passed as an argument. I have demonstrated that in post #2 of that CodeBank thread.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  9. #9

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Invalid URI & "Not Responding" fix

    Quote Originally Posted by jmcilhinney View Post
    As I have said in this thread and demonstrated in my CodeBank thread, you cannot access controls directly in the DoWork event handler. That means that any data you need from the UI in the DoWork event handler has to be gathered up before you call RunWorkerAsync and then passed as an argument. I have demonstrated that in post #2 of that CodeBank thread.
    Sorry, I was reading the wrong thread but I have read it and I don't really understand..
    Maybe this just wasn't meant to be fixed.

  10. #10
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Invalid URI & "Not Responding" fix

    If you'd care to elaborate then maybe we can help you learn something. Do you not understand the examples provided or do you not understand how to implement the principles in your own project?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  11. #11
    Frenzied Member
    Join Date
    Mar 2005
    Location
    Sector 001
    Posts
    1,577

    Re: Invalid URI & "Not Responding" fix

    Do you actually get a "Not Responding" error or does your program simply hang waiting for a non existing page to load? If the latter, a second thread solution won't really help. You'd have a responding UI but no progress since the wait won't be interrupted. The webclient does not have an exposed timeout property but since you are using DownloadStringAsync you could simply get a timer to cancel the download after X amount of time has elapsed (and move on).

    Or use to a WebRequest + WebResponse directly. The combination allows for setting timeouts.

    Or prefilter the list in advance by pinging each site and if you get a reply add it to the list to check. Not all sites that are up will respond though. Vbforums.com won't for example

    In any case you'd have to tweak your code somewhat but the WebClient is really only good for things that are sure to exist and be always accessible.
    VB 2005, Win Xp Pro sp2

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Invalid URI & "Not Responding" fix

    @jmcilhinney
    @Half
    I have updated my thread.
    check it out
    Last edited by Bizzet; Oct 29th, 2012 at 07:00 PM.

  13. #13

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Invalid URI & "Not Responding" fix

    Quote Originally Posted by jmcilhinney View Post
    If you'd care to elaborate then maybe we can help you learn something. Do you not understand the examples provided or do you not understand how to implement the principles in your own project?
    I do not understand how to implement them into my own project. I would not say I need to be spoon-fed the exact code for my program but I need an example more related to my own project.

  14. #14
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    That would be spoon-feeding. I've already provided an example that passes data into the DoWork event handler via the RunWorkerAsync method and executes a For loop based on that input. How much more related to your own project do you want? The steps are very simple:

    1. Gather up any data from the UI that will be needed by the background task.
    2. Call RunWorkerAsync and pass the data gathered in step 1.
    3. Handle DoWork and get the data passed in step 2 from the e.Argument property.
    4. Do the work in the DoWork event handler.
    5. If you need to update the UI during the task, call ReportProgress and pass and data required.
    5a. Handle ProgressChanged, get the data passed in step 5 from the e.ProgressPercentage and/or e.UserState properties and update the UI.
    6. If you need to update the UI after the task, assign any data required to the e.Result property.
    6a. Handle RunWorkerCompleted, get the data passed in step 6 from the e.Result property and update the UI.

    Every one of those steps is demonstrated in my CodeBank thread. If you've followed my instructions so far then you have put all the code relating to the task in its own method. It's obvious from that method where you are using data that comes from a control so that is the data that you need to gather for step 1. Show me that.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  15. #15

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    Quote Originally Posted by jmcilhinney View Post
    That would be spoon-feeding. I've already provided an example that passes data into the DoWork event handler via the RunWorkerAsync method and executes a For loop based on that input. How much more related to your own project do you want? The steps are very simple:

    1. Gather up any data from the UI that will be needed by the background task.
    2. Call RunWorkerAsync and pass the data gathered in step 1.
    3. Handle DoWork and get the data passed in step 2 from the e.Argument property.
    4. Do the work in the DoWork event handler.
    5. If you need to update the UI during the task, call ReportProgress and pass and data required.
    5a. Handle ProgressChanged, get the data passed in step 5 from the e.ProgressPercentage and/or e.UserState properties and update the UI.
    6. If you need to update the UI after the task, assign any data required to the e.Result property.
    6a. Handle RunWorkerCompleted, get the data passed in step 6 from the e.Result property and update the UI.

    Every one of those steps is demonstrated in my CodeBank thread. If you've followed my instructions so far then you have put all the code relating to the task in its own method. It's obvious from that method where you are using data that comes from a control so that is the data that you need to gather for step 1. Show me that.
    This is where I am stuck:
    4. Do the work in the DoWork event handler.
    Can't find a way to implement my code into the DoWork, an error always pops up.

  16. #16
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    If step 4 is where you're stuck then that suggests that you've done steps 1, 2 & 3. Can you show us that? As for step 4, what's the code you've tried and what's the error that pops up?

    That said, you shouldn't have to find a way because it should already be done. I said in the first place to move the task into its own method so that it works on a single thread? Did do that? If so then you already have the implementation. The next step was to move that code into the DoWork event handler. Then it's a matter of identifying each place that you're taking input from the UI or sending output to the UI and replacing them exactly as I have already explained how: input comes in from the RunWorkerAsync method via the e.Argument property and output goes out via ReportProgress, ProgressChanged and RunWorkerCompleted.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  17. #17

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    Here is method 1: http://tny.cz/ac1add83

    Here is method 2: http://tny.cz/459eafc4

    Here is method 3: http://tny.cz/143ede67

    They all do not do anything. :/ and I can't really understand all the VB lingo so this is the best I could do from what you gave me.
    Please explain further of these examples.

  18. #18
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    Firstly, please post your code snippets in your post using the appropriate formatting tags.

    As for the issue, in none of those examples are you doing what I said. I have said more than once that, if you need to use any data from the UI in the DoWork event handler, you need to gather that data BEFORE you call RunWorkerAsync and pass it as an argument, getting it back via the e.Argument property. I have demonstrated that in my CodeBank thread using a NumericUpDown control. In all those code snippets you provided you are not passing anything to RunWorkerAsync and you are getting data directly from a control. This is from all three of your code snippets:
    Code:
    For I As Integer = 0 To Website_list.Items.Count - 1
    What is Website_list? Is it not a control? Then you have to do as I have already said more than once. Get the data you need from it before you call RunWorkerAsync and pass it in, just as I have demonstrated in the CodeBank. You keep saying that you need an example that's like your scenario but you already have one.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  19. #19

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    Quote Originally Posted by jmcilhinney View Post
    Firstly, please post your code snippets in your post using the appropriate formatting tags.

    As for the issue, in none of those examples are you doing what I said. I have said more than once that, if you need to use any data from the UI in the DoWork event handler, you need to gather that data BEFORE you call RunWorkerAsync and pass it as an argument, getting it back via the e.Argument property. I have demonstrated that in my CodeBank thread using a NumericUpDown control. In all those code snippets you provided you are not passing anything to RunWorkerAsync and you are getting data directly from a control. This is from all three of your code snippets:
    Code:
    For I As Integer = 0 To Website_list.Items.Count - 1
    What is Website_list? Is it not a control? Then you have to do as I have already said more than once. Get the data you need from it before you call RunWorkerAsync and pass it in, just as I have demonstrated in the CodeBank. You keep saying that you need an example that's like your scenario but you already have one.
    Maybe I am reading the wrong thread or I just can't understand? I understand that you can get the count from the listbox cause it's running in the background but HOW DO I DO IT THEN!!?
    Give me the link...
    Cause I am about to be done at this point.

  20. #20
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    I've already given you the link. Have you read post #2 of my CodeBank thread on Using The BackgroundWorker or not?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  21. #21

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    Quote Originally Posted by jmcilhinney View Post
    I've already given you the link. Have you read post #2 of my CodeBank thread on Using The BackgroundWorker or not?
    No actually, I had not read it, but now I have an I've made a little more progress.

    Code:
        Private Sub btnLeech_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Leech_btn.Click
            Worker.RunWorkerAsync((CInt(Me.Website_list.Items.Count)))
        End Sub
    
        'Open a bunch of new threads to download sources of webpages
        Private Sub Fetch(ByVal sender As System.Object, _
                                         ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Worker.DoWork
            Dim websiteUri As Uri = Nothing
            Dim Website As String
            Dim Count As Integer
            For I As Integer = 0 To Count
                If TypeOf e.Argument Is Integer Then
                    Count = CInt(e.Argument)
                End If
    
                Using wc As Net.WebClient = New Net.WebClient
                    AddHandler wc.DownloadStringCompleted, AddressOf SourceDownloaded
                    If Uri.TryCreate(Website, UriKind.Absolute, websiteUri) Then
                        wc.DownloadStringAsync(New Uri(Website))
                        Worker.ReportProgress(I, I & " iterations complete")
                        Threading.Thread.Sleep(250)
                    Else
                        If Notify.Checked = True Then
                            TrayIcon.ShowBalloonTip(1, "Invalid website", "There was a invalid site in the list." & Website.ToString, ToolTipIcon.Error)
                            Me.TrashSite_list.Items.Add(Website)
                        Else
                            Me.TrashSite_list.Items.Add(Website)
                        End If
                    End If
                End Using
            Next
        End Sub
    But how do I do this in Backgroundworker:
    Code:
    Website = Me.Website_list.Items.Item(I)

  22. #22
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    So I basically gave you the answer two days ago and we've been going back and forth all this time and you didn't even read it? That's a big waste of my time and yours. In future, if someone tells you where to find information, I suggest that you actually look at it before you start asking for anything more.

    Anyway, we'll start a fresh. As I've said numerous times, any data that you need in the DoWork event handler must be gathered before you call RunWorkerAsync and passed in as an argument. If you need the items from the ListBox then you need to gather the items from the ListBox and pass those in. The 'argument' parameter of the RunWorkerAsync method and the e.Argument property in the DoWork event handler are declared as type Object specifically so that you can pass any type of object. It might be an Integer, a String, an array, a DataSet or some other complex type that consists of hundreds of objects related via properties. It can be absolutely anything so that every developer can use it for exactly what they need.

    In your case, if what you need in the DoWork event handler from the UI is the items from the ListBox then you need to package up those items in an appropriate data structure and pass that. You can't just pass the Items collection because that's still linked directly to the ListBox. The most obvious solution is to create an array, copy the items from the ListBox into it and then pass that. That solves the issue of the loop bounds too, because you simply loop through that array just as you would any other. In fact, it would probably make more sense to use a For Each loop than a For loop, unless you specifically need the index for some purpose other than getting the item.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  23. #23

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    Well, I did read it, just the first part though. I had no idea it continued when the thread was over. I moved on to a different thread of yours related to BGWs and I thought that was the one I was suppose to read. I got all mixed up. Anyways, I added my listbox to an array and tried to add it to the BGW but its got a null error

    Code:
        'Leech Button
    
        Private Sub btnLeech_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Leech_btn.Click
            Dim Array() As String = Website_list.Items.OfType(Of String)().ToArray()
            Worker.RunWorkerAsync(Array)
        End Sub
    
        'Open a bunch of new threads to download sources of webpages
        Private Sub Fetch(ByVal sender As System.Object, _
                                         ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Worker.DoWork
            Dim websiteUri As Uri = Nothing
            Dim Website As String
            Dim SiteList6() As String = e.Argument.ToString.Split
            For I = 0 To e.Argument.ToString.Length
                Website = e.Argument(I)
                Using wc As Net.WebClient = New Net.WebClient
                    AddHandler wc.DownloadStringCompleted, AddressOf SourceDownloaded
                    If Uri.TryCreate(Website, UriKind.Absolute, websiteUri) Then
                        wc.DownloadStringAsync(New Uri(Website))
                        Worker.ReportProgress(I, I & " iterations complete")
                        Threading.Thread.Sleep(250)
                    Else
                        If Notify.Checked = True Then
                            TrayIcon.ShowBalloonTip(1, "Invalid website", "There was a invalid site in the list." & Website.ToString, ToolTipIcon.Error)
                            Me.TrashSite_list.Items.Add(Website)
                        Else
                            Me.TrashSite_list.Items.Add(Website)
                        End If
                    End If
                End Using
            Next
        End Sub
        'Grab the proxies from the webpages
        Private Sub SourceDownloaded(ByVal sender As Object, ByVal e As Net.DownloadStringCompletedEventArgs)
            Dim strRegex As String = "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\:[0-9]{1,5}\b"
            Dim myRegexOptions As RegexOptions = RegexOptions.None
            Dim myRegex As New Regex(strRegex, myRegexOptions)
            Dim frm As New Proxies
            My.Settings.Proxies = New StringCollection
            If e.Error Is Nothing Then
                For Each myMatch As Match In myRegex.Matches(e.Result)
                    If myMatch.Success Then
                        Try
                            My.Settings.Proxies.Add(myMatch.ToString)
                        Catch ex As WebException
                            MessageBox.Show(
                                ex.ToString,
                                ErrorToString,
                                Windows.Forms.MessageBoxButtons.OK)
                        End Try
                    End If
                Next
            End If
        End Sub
    
        Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
            Website_list.Items.Clear()
            Dim Proxies() As String = My.Resources.SiteList6.Split(vbNewLine)
            Proxy_list.Items.AddRange(Proxies)
            Proxy2_lbl.Text = "Proxies: " & Proxy2_list.Items.Count
            Proxy_lbl.Text = "Proxies: " & Proxy2_list.Items.Count
    
    
            Me.Label1.Text = TryCast(e.UserState, String)
        End Sub
    #End Region
    It doesn't update my listbox? How come?
    I got no errors finally!!!!!!!

  24. #24
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    This will be my last post to this thread. The following example populates a ListBox with 10 random numbers and then, using a BackgroundWorker, copies the even numbers to a second ListBox and the odd numbers to a third. It's a very contrived example but it demonstrates all the principles required, even though you already have examples of them all anyway.
    vb.net Code:
    1. Public Class Form1
    2.  
    3.     Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4.         Dim rng As New Random
    5.  
    6.         For i = 1 To 10
    7.             ListBox1.Items.Add(rng.Next())
    8.         Next
    9.     End Sub
    10.  
    11.     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    12.         Dim numbers = ListBox1.Items.Cast(Of Integer).ToArray()
    13.  
    14.         BackgroundWorker1.RunWorkerAsync(numbers)
    15.     End Sub
    16.  
    17.     Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    18.         Dim numbers = DirectCast(e.Argument, Integer())
    19.         Dim oddCount = 0
    20.         Dim evenCount = 0
    21.  
    22.         For Each number As Integer In numbers
    23.             If number Mod 2 = 0 Then
    24.                 BackgroundWorker1.ReportProgress(number, ListBox2)
    25.                 evenCount += 1
    26.             Else
    27.                 BackgroundWorker1.ReportProgress(number, ListBox3)
    28.                 oddCount += 1
    29.             End If
    30.         Next
    31.  
    32.         e.Result = Tuple.Create(oddCount, evenCount)
    33.     End Sub
    34.  
    35.     Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    36.         Dim number = CInt(e.ProgressPercentage)
    37.         Dim target = DirectCast(e.UserState, ListBox)
    38.  
    39.         target.Items.Add(number)
    40.     End Sub
    41.  
    42.     Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    43.         Dim counts = DirectCast(e.Result, Tuple(Of Integer, Integer))
    44.  
    45.         MessageBox.Show(String.Format("{0} odd numbers and {1} even numbers were copied.", counts.Item1, counts.Item2))
    46.     End Sub
    47.  
    48. End Class
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  25. #25

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    hey jmc! I would just like to not thank you for everything you have told me. I have actually learned that your teachings have actually prevented me from reaching my goal.

    You straight up told me :
    As I've said numerous times, any data that you need in the DoWork event handler must be gathered before you call RunWorkerAsync and passed in as an argument. If you need the items from the ListBox then you need to gather the items from the ListBox and pass those in.
    When really, that is not true. As you can see in my new WORKING code:

    Code:
    #Region "Leech Proxies"
    
        'When this button is pressed, the leeching process starts and the MainForm minimizes if the setting was clicked on the HomePage.
        Private Sub Start_Leeching(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Leech_btn.Click
            If Mini.Checked = False Then
                If Websites_list.Items.Count > 0 Then
                    Checker.Enabled = False
                    Home.Enabled = False
                    If Leeching.IsBusy = False Then
                        Leeching.RunWorkerAsync()
                    End If
                End If
            Else
                If Websites_list.Items.Count > 0 Then
                    Me.WindowState = FormWindowState.Minimized
                    Me.Visible = False
                    TrayIcon.Visible = True
                    Leeching.RunWorkerAsync()
                End If
            End If
        End Sub
    
        'Grab the proxies from the websites in Websites_list and makes sure they in proxy format in the background.
        Private Sub wrk_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles Leeching.DoWork
            Dim Website As String
            Dim websiteUri As Uri = Nothing
    
            Dim strRegex As String = "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\:[0-9]{1,5}\b"
            Dim myRegexOptions As RegexOptions = RegexOptions.None
            Dim myRegex As New Regex(strRegex, myRegexOptions)
    
            For Each Website In Websites_list.Items
                Try
                    Using wc As Net.WebClient = New Net.WebClient
                        If Uri.TryCreate(Website, UriKind.Absolute, websiteUri) Then
                            Dim page As String = wc.DownloadString(New Uri(Website))
                            For Each myMatch As Match In myRegex.Matches(page)
                                If myMatch.Success Then
                                    'This is how backgroundworkers notify that something is going on.
                                    'Consider that ReportProgress is executed in the main thread,
                                    'so you don't have to worry about CrossThread exceptions.
                                    'Here 0 is not real progress, but this integer could be used
                                    'as placeholder to understand what UserState contains.
                                    Leeching.ReportProgress(0, myMatch.ToString)
                                End If
                            Next
                        End If
                    End Using
                Catch ex As Exception
    
                End Try
            Next
        End Sub
    
        'When the backgroundworker is complete
        Private Sub wrk_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles Leeching.ProgressChanged
            Dim proxy As String = e.UserState
            Try
                Proxies_list2.Items.Add(proxy)
                Proxies_List.Items.Add(proxy)
                Proxies_lbl2.Text = "Proxies: " & Proxies_list2.Items.Count
                Proxies_lbl.Text = "Proxies: " & Proxies_list2.Items.Count
    
                'These lines could be added to let listboxes refreshed while adding items
                'Note that I do it only every 50 cycles to avoid flickering and a slow code
                If (Proxies_list2.Items.Count Mod 100 = 0) Then
                    Proxies_list2.Invalidate()
                    Proxies_list2.Refresh()
    
                    Proxies_List.Invalidate()
                    Proxies_List.Refresh()
    
                    Proxies_lbl2.Invalidate()
                    Proxies_lbl2.Refresh()
    
                    Proxies_lbl.Invalidate()
                    Proxies_lbl.Refresh()
                End If
                '-------------------------------------------------------------------------
    
            Catch ex As WebException
                MessageBox.Show(
                    ex.ToString,
                    ErrorToString,
                    Windows.Forms.MessageBoxButtons.OK)
            End Try
        End Sub
    
        'Refreshes all the listboxes and labels when the Leeching is complete.
        Private Sub wrk_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Leeching.RunWorkerCompleted
            Proxies_list2.Invalidate()
            Proxies_list2.Refresh()
    
            Proxies_List.Invalidate()
            Proxies_List.Refresh()
    
            Proxies_lbl2.Invalidate()
            Proxies_lbl2.Refresh()
    
            Proxies_lbl.Invalidate()
            Proxies_lbl.Refresh()
        End Sub
    #End Region
    I don't mean to sound like an *******, but seriously? It's that simple but you had to make it so ****ing hard on me. Spending hours trying to fix a simple solution is not something that helps me develop my knowledge, if that's what you were trying to do.

  26. #26
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    I made it easy for you. I gave you simple instructions that you refused to follow. You made it hard on yourself.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  27. #27

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    Quote Originally Posted by jmcilhinney View Post
    I made it easy for you. I gave you simple instructions that you refused to follow. You made it hard on yourself.
    Only problem with that is.
    Your simple =/= My simple
    Your simple =/= The SIMPLEST

  28. #28
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Adding a For statement into a Backgroundworker

    From post #6:
    Quote Originally Posted by jmcilhinney
    you should start by moving your long-running task into its own method
    Never saw that done. Also from post #6:
    Quote Originally Posted by jmcilhinney
    For some examples, follow the CodeBank link in my signature and check out my thread on Using The BackgroundWorker.
    From post #21, 15 posts later:
    Quote Originally Posted by Bizzet
    No actually, I had not read it
    You can whine all you want but the simple fact is that you didn't stop and follow instructions. Goodbye.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  29. #29

    Thread Starter
    Junior Member
    Join Date
    Apr 2011
    Posts
    19

    Re: Adding a For statement into a Backgroundworker

    I'll explain everything I was thinking at the point I first saw it.
    Okay, first off, if your explaining something to someone who is trying to learn something new, use more specific terms. "Method" could refer to a sub or a function, but SourceDownloaded was already in it's own sub so what the hell am I suppose to do at this point?
    I DO NOT KNOW BECAUSE I DO NOT KNOW VB.NET WELL! THAT'S WHAT YOUR SUPPOSE TO BE TELLING ME.
    Then, I start to follow the examples you posted but it not anything like I've seen before and it's not really even related to my project to understand without explanation.
    WHICH YOU ARE SUPPOSE TO EXPLAIN!

    Quote Originally Posted by Bizzet
    Well, I did read it, just the first part though. I had no idea it continued when the thread was over. I moved on to a different thread of yours related to BGWs and I thought that was the one I was suppose to read. I got all mixed up.
    That easily explains my reasoning for not reading the whole thread and not one part of that is false. Even after reading your thread completely I did not understand. Why? I needed personal help, just what I had asked for when posting this thread.

    And in the end, none of this explains why you told me I could not gather any data from the form in the backgroundworker, which made me almost give up. Good thing that is not the case.
    Helping or Preventing?, preventing in my case.

Tags for this Thread

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