1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Question regarding BackroundWorker

Discussion in 'Visual Basic .NET' started by fpforum, Jan 3, 2013.

  1. fpforum

    fpforum Junior Member

    Joined:
    Apr 22, 2008
    Messages:
    117
    Likes Received:
    4
    Home Page:
    Hey everyone..I've been trying to finish a small aol account checker and i'm having some problems getting it to run in a thread. For some reason whenever I press the start button it selects the first item and just sits there...

    Here is the start button code..this makes sure there's at least one account in the listbox and then kicks off the thread
    Code:
            If lstAccts.Items.Count = 0 Then
                MsgBox("Please Add Some Accounts!")
                Exit Sub
            Else
                txtLog.AppendText("Started Checking Accounts at: " & Now & vbCrLf)
                txtLog.Refresh()
                lstAccts.SetSelected(0, True)
                BackgroundWorker1.RunWorkerAsync()
            End If
    
    Here is the thread that kicks off where it should be looping through the list..
    Code:
        Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
            For i As Integer = 0 To lstAccts.Items.Count - 1
                selectedAccount = lstAccts.Items(i).ToString
    
                Dim line As String = selectedAccount
    
                parts = line.Split(":")
    
                Dim Username As String = parts(0) 'The Aol screen name
                Dim Password As String = parts(1) 'The Aol password
                Dim Post As String = "/_cqr/login/login.psp sitedomain=startpage.aol.com&siteId=&lang=en&locale=us&authLev=0&siteState=OrigUrl%253Dhttp%25253A%25252F%25252Fwww.aol.com%25252F&isSiteStateEncoded=true&mcState=initialized&uitype=std&use_aam=0&offerId=&seamless=y&regPromoCode=&usrd=1795702&doSSL=&redirType=&xchk=false&tab=&lsoDP=id%3DE972048F-57EC-62F4-2F30-2E5009CA0C6C&loginId={0}&password={1}"
                Post = String.Format(Post, Username, Password) 'Password(I))
                Dim InformationA As String
                Cookies = New CookieContainer()
                Dim Encoding As New ASCIIEncoding()
                Dim Data As Byte() = Encoding.GetBytes(Post)
                Dim Request As HttpWebRequest = DirectCast(WebRequest.Create("https://my.screenname.aol.com/_cqr/login/login.psp?sitedomain=startpage.aol.com&siteState=OrigUrl%3dhttp%253A%252F%252Fwww.aol.com%252F&authLev=0&lang=en&locale=us"), HttpWebRequest)
                Request.Method = "POST"
                Request.UserAgent = ".NET Example Client"
                Request.ContentType = "application/x-www-form-urlencoded"
                Request.CookieContainer = Cookies
                Dim DataStream As Stream = Request.GetRequestStream()
                DataStream.Write(Data, 0, Data.Length)
                Dim Response As HttpWebResponse = DirectCast(Request.GetResponse(), HttpWebResponse)
                Dim SR As New StreamReader(Response.GetResponseStream())
                InformationA = SR.ReadToEnd()
                InformationB = InformationA
                BackgroundWorker1.ReportProgress(selectedAccount)
                Response.Close()
            Next
        End Sub
    
    Code:
        Private Sub Worker_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
            Dim newItem As Integer = CInt(e.UserState)
            If InformationB.Contains("Username Service") Then
                txtLog.AppendText("Successfully Logged into:" & newItem & " at: " & TimeOfDay & vbCrLf)
                lstGoodAccounts.Items.Add(newItem)
            ElseIf InformationB.Contains("Incorrect Username") Then
                txtLog.AppendText("Incorrect Login Details for Account: " & parts(0) & " at: " & TimeOfDay & vbCrLf)
            Else
                txtLog.AppendText("Unknown Login Error for Account: " & parts(0) & " at: " & TimeOfDay & vbCrLf)
            End If
        End Sub
    
    and then finally..
    Code:
        Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
            If e.Cancelled = True Then
                txtLog.AppendText("Canceled!")
            ElseIf e.Error IsNot Nothing Then
                txtLog.AppendText("Error: " & e.Error.Message)
            Else
                txtLog.AppendText("Done!")
            End If
        End Sub
    
    Can anybody tell me where I'm going wrong at here? It should select the first item in the listbox, kick off the thread which will then check each account and will cancel if the stop button is clicked..
    Thanks!
     
  2. Psychop1

    Psychop1 Registered Member

    Joined:
    Jul 30, 2010
    Messages:
    63
    Likes Received:
    19
    I've not been through all the code, but I think the issue may be trying to access a user interface control (a listbox or listview possibly) from the dowork event. I don't remember why, but I'm pretty sure the background worker dowork event has issues with user interface controls. You can try to work around this, such as possibly populating a list or array with the values you need before triggering the dowork event and use that instead of the user interface control, but I would suggest looking into multithreading and delegates. I won't use background worker myself. Again, I haven't been through all the code and I'm not sure if this is the central issue, but if you have the dowork event accessing a user interface control, I would eliminate the need for that first.
     
  3. ultra.marine

    ultra.marine Registered Member

    Joined:
    Oct 5, 2012
    Messages:
    80
    Likes Received:
    101
    Location:
    Macedonia
    You need to use DELEGATE in order to do operations between threads. I am not sure you can access the items created in other thread.
    You should try using this





    'Create function that retreives the old list

    Public function getList()
    return oldList
    end function

    'create delegate
    public delegate function getListSafe()

    'inside the background
    Dim list as new list (of something)
    Dim someone as new getListSafe(address of getList)
    list=me.invoke(someone)

    then loop through the list created inside the background process

    Hope that help
     
  4. healzer

    healzer Jr. Executive VIP Jr. VIP Premium Member

    Joined:
    Jun 26, 2011
    Messages:
    2,363
    Likes Received:
    1,966
    Gender:
    Male
    Occupation:
    Marketing automation tools
    Location:
    Somewhere in Europe
    Home Page:
    (I havent gone through your code but from the replies above I'll go with the fact its cross-thread-operation-failure thing)
    so if it is a cross-thread just use the following whenever you Access/trigger/change any other control on the form from a backgroundWoker (or other thread)

    (use the following code on your backgroundWorker code fcours):

    Code:
    If myItem.InvokeRequired Then
    myItem.Invoke(Sub() myItem.Visible = True)
    End If

    replace myItem by your listbox or textbox or w/e it is
    replace myItem.Visible by your operation you are trying to do (adding into a listbox or changing text, w/e, ...)
     
    • Thanks Thanks x 1
  5. ultra.marine

    ultra.marine Registered Member

    Joined:
    Oct 5, 2012
    Messages:
    80
    Likes Received:
    101
    Location:
    Macedonia
    You are trying to do cross-thread operations that's why it fails, use delegate in order to do that
    example


    Code:
    'create function that retreives the list you work with
    public function returnList()
    return 
    end function
    
    'create delegate
    Delegate function returnListSafe()
    end function
    
    'Inside the background worker declare new list
    Dim newList as new list (of something)
    'create object of delegate
    Dim whynow as new returnListSafe(address of returnList)
    
    'Make the new list be the same as the old
    newList=me.invoke(whynow)
    
    'Now do your looping through newList and ignore your old list
    
     
    • Thanks Thanks x 1
  6. Psychop1

    Psychop1 Registered Member

    Joined:
    Jul 30, 2010
    Messages:
    63
    Likes Received:
    19
    If you're using delegates, you might as well go all the way with multithreading. Alternatively, you could create two global variables - one an integer and one a list of string. You could then set the integer variable to your listview item count and loop through your listview items to populate your list (be sure you clear the list before running the loop). You could then use these variables in your dowork thread. I went ahead and looked at a backgroundworker's properties. Do you have workerreportsprogress set to true? I don't think the progresschanged event will trigger if it isn't set to true.
     
  7. Psychop1

    Psychop1 Registered Member

    Joined:
    Jul 30, 2010
    Messages:
    63
    Likes Received:
    19
    I'll add that Ultra Marine's example is a good example of accessing a thread from another thread. A lot of people struggle with delegates but it really isn't that hard once you wrap your mind around it. Once you do wrap your mind around it, you'll realize that you don't need background workers. I've never used healzer's example, but it may be the simplest way to do what you want.
     
    • Thanks Thanks x 2
  8. fpforum

    fpforum Junior Member

    Joined:
    Apr 22, 2008
    Messages:
    117
    Likes Received:
    4
    Home Page:
    Thanks for all the input and tips guys! It was infact a cross-thread error and it looks like healzer's post did fix selecting and going through the account list. However, the good accounts are not being moved into the "Good Account" listbox and the status isn't being updated in the txtLog. I'm going to look into ultra.marine's method now and see how that does...Thanks for all the helpful replies!!
     
    • Thanks Thanks x 1
  9. fpforum

    fpforum Junior Member

    Joined:
    Apr 22, 2008
    Messages:
    117
    Likes Received:
    4
    Home Page:
    Edit: Figured it out..I was starting the background worker twice..lol
     
    Last edited: Jan 5, 2013
  10. eried

    eried Newbie

    Joined:
    Jan 17, 2013
    Messages:
    14
    Likes Received:
    10
    Location:
    Chile
    Home Page:
    hahaha, something useful to remember too is to add try and Catch to the DoWork routine, and a breakpoint in the catch, because it is common to lose errors inside the doWork event