|
-
Oct 27th, 2012, 01:04 AM
#1
Thread Starter
Junior Member
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
-
Oct 27th, 2012, 05:30 AM
#2
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.
-
Oct 27th, 2012, 11:51 AM
#3
Thread Starter
Junior Member
Re: Invalid URI & "Not Responding" fix
 Originally Posted by Half
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..
-
Oct 27th, 2012, 11:59 AM
#4
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.
-
Oct 27th, 2012, 10:14 PM
#5
Thread Starter
Junior Member
Re: Invalid URI & "Not Responding" fix
 Originally Posted by jmcilhinney
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.
-
Oct 27th, 2012, 11:22 PM
#6
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.
-
Oct 28th, 2012, 12:30 AM
#7
Thread Starter
Junior Member
Re: Invalid URI & "Not Responding" fix
 Originally Posted by jmcilhinney
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?
-
Oct 28th, 2012, 01:10 AM
#8
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.
-
Oct 28th, 2012, 01:30 AM
#9
Thread Starter
Junior Member
Re: Invalid URI & "Not Responding" fix
 Originally Posted by jmcilhinney
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.
-
Oct 28th, 2012, 02:52 AM
#10
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?
-
Oct 29th, 2012, 06:10 PM
#11
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.
-
Oct 29th, 2012, 06:30 PM
#12
Thread Starter
Junior Member
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.
-
Oct 29th, 2012, 06:59 PM
#13
Thread Starter
Junior Member
Re: Invalid URI & "Not Responding" fix
 Originally Posted by jmcilhinney
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.
-
Oct 29th, 2012, 07:11 PM
#14
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.
-
Oct 29th, 2012, 08:06 PM
#15
Thread Starter
Junior Member
Re: Adding a For statement into a Backgroundworker
 Originally Posted by jmcilhinney
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.
-
Oct 29th, 2012, 08:20 PM
#16
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.
-
Oct 29th, 2012, 08:54 PM
#17
Thread Starter
Junior Member
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.
-
Oct 29th, 2012, 09:15 PM
#18
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.
-
Oct 29th, 2012, 09:32 PM
#19
Thread Starter
Junior Member
Re: Adding a For statement into a Backgroundworker
 Originally Posted by jmcilhinney
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.
-
Oct 29th, 2012, 10:28 PM
#20
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?
-
Oct 29th, 2012, 11:37 PM
#21
Thread Starter
Junior Member
Re: Adding a For statement into a Backgroundworker
 Originally Posted by jmcilhinney
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)
-
Oct 30th, 2012, 12:08 AM
#22
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.
-
Oct 30th, 2012, 01:52 AM
#23
Thread Starter
Junior Member
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!!!!!!!
-
Oct 30th, 2012, 06:09 AM
#24
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:
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim rng As New Random For i = 1 To 10 ListBox1.Items.Add(rng.Next()) Next End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim numbers = ListBox1.Items.Cast(Of Integer).ToArray() BackgroundWorker1.RunWorkerAsync(numbers) End Sub Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork Dim numbers = DirectCast(e.Argument, Integer()) Dim oddCount = 0 Dim evenCount = 0 For Each number As Integer In numbers If number Mod 2 = 0 Then BackgroundWorker1.ReportProgress(number, ListBox2) evenCount += 1 Else BackgroundWorker1.ReportProgress(number, ListBox3) oddCount += 1 End If Next e.Result = Tuple.Create(oddCount, evenCount) End Sub Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged Dim number = CInt(e.ProgressPercentage) Dim target = DirectCast(e.UserState, ListBox) target.Items.Add(number) End Sub Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted Dim counts = DirectCast(e.Result, Tuple(Of Integer, Integer)) MessageBox.Show(String.Format("{0} odd numbers and {1} even numbers were copied.", counts.Item1, counts.Item2)) End Sub End Class
-
Nov 6th, 2012, 07:23 PM
#25
Thread Starter
Junior Member
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.
-
Nov 6th, 2012, 07:43 PM
#26
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.
-
Nov 6th, 2012, 07:50 PM
#27
Thread Starter
Junior Member
Re: Adding a For statement into a Backgroundworker
 Originally Posted by jmcilhinney
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
-
Nov 6th, 2012, 08:12 PM
#28
Re: Adding a For statement into a Backgroundworker
From post #6:
 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:
 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:
 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.
-
Nov 6th, 2012, 08:30 PM
#29
Thread Starter
Junior Member
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!
 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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|