Results 1 to 15 of 15

Thread: Backgroundworker with public function and listbox

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    353

    Unhappy Backgroundworker with public function and listbox

    Hi,

    I'm struggling with a thing or two...and i've read some stuff about the backgroundworker but im stuck

    Basically what i have is a :

    PUBLIC FUNCTION TEST (path as string) : which at the end of work , adds an item to the form1.listbox. That works quite nice but freezes the app.

    I've tried using the backgroundworker, the function in the background worker seems to work nicely, the bad thing is that i dont get any results in the form1.listbox.

    Any ideas on how to make the listbox add items??

    Cheers!
    Thanks for helping me out.

  2. #2
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Re: Backgroundworker with public function and listbox

    No idea what your code looks like.

    I'd suggest starting here: http://vbnotebookfor.net/2007/09/24/...rker-in-vbnet/
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

  3. #3
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Backgroundworker with public function and listbox

    You probably need to use a delegate sub/function in order to update the form's control on the fly.

    So:

    vb Code:
    1. private delegate sub Del_AddListBoxItem(value as string)

    Then in your DoWork method or whatever method the background worker performs you would have something like:

    vb Code:
    1. Public Function (path as string) As Boolean 'don't know what you want to return.
    2.  
    3. // work done
    4.  
    5. Dim d as new Del_AddListBoxItem(AddressOf formAddListBoxItem)
    6. Me.Invoke(d, new object(){"testItem"})
    7. End Function

    You'll have to have a Public or Private Sub called 'myAddListBoxItem'.

    Would look something like:

    vb Code:
    1. Private Sub myAddListBoxItem(value as string)
    2.  
    3. Me.ListBox1.Items.Add(value)
    4.  
    5. End Sub

    Basically this is required when you are trying to update a GUI control from a thread other than the one
    the form was created on.

    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    353

    Re: Backgroundworker with public function and listbox

    i'll check it out ..

    well basically...my public function does calculations and adds results to the main form's listbox.


    so , when i add that function in the backgroundworker_dowork sub, the calculations withing the public function are being made whilte the result does not get printed out on the main form listbox.
    Thanks for helping me out.

  5. #5
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Backgroundworker with public function and listbox

    Declare a delegate sub/function with the same parameter signature like in my previous post.
    Create a public/private sub/function with the same declaration as the delegate like in my previous post.

    Instead of calling ListBox1.Items.Add(value) directly in your backgroundworker_dowork sub, use the form's Invoke method like in my previous post.

    See if that gets the listbox populated.

    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    353

    Re: Backgroundworker with public function and listbox

    First of all, thank you very much for your help!

    This is the error i get :

    Error on: Form1.lstScreens.Invoke(d, New Object, {"testItem"})

    Reason : Invoke or BeginInvoke cannot be called on a control until the window handle has been created.


    This is what i did:

    Code:
    Public Delegate Sub Del_AddListBoxItem(ByVal value As String)
    Code:
    Public Function Test() as String
    
    // WORK DONE
    
    Dim d As New Del_AddListBoxItem(AddressOf myAddListBoxItem)
    Form1.lstScreens.Invoke(d, New Object, {"testItem"})
    
    End Function

    Code:
    Public Sub myAddListBoxItem(ByVal value As String)
    
            Form1.listbox1.Items.Add(value)
    
        End Sub
    Thanks for helping me out.

  7. #7
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Backgroundworker with public function and listbox

    Form1.lstScreens.Invoke(d, New Object, {"testItem"})

    should be

    Form1.Invoke(d, New Object(){"TheValueYouWantToAdd"})

    or

    Me.Invoke(d, New Object(){"TheValueYouWantToAdd"})

    Me, referring to the form the backgroundworker has been dropped on.

    Are you starting the Worker in the form_load?

    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  8. #8
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Re: Backgroundworker with public function and listbox

    Quote Originally Posted by MonkOFox View Post
    Declare a delegate sub/function with the same parameter signature like in my previous post.
    Create a public/private sub/function with the same declaration as the delegate like in my previous post.

    Instead of calling ListBox1.Items.Add(value) directly in your backgroundworker_dowork sub, use the form's Invoke method like in my previous post.

    See if that gets the listbox populated.

    Justin
    The whole point of the BackgroundWorker is so you don't have to manually do this.

    YourBackgroundWorker.ReportProgress lets you send ProgressPercentage and UserState to the YourBackgrounWorker_ProgressChanged event. From there you can update any controls on the UI.

    The link I posted goes through all of this step by step.
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

  9. #9

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    353

    Re: Backgroundworker with public function and listbox

    Quote Originally Posted by MonkOFox View Post
    You probably need to use a delegate sub/function in order to update the form's control on the fly.

    So:

    vb Code:
    1. private delegate sub Del_AddListBoxItem(value as string)

    Then in your DoWork method or whatever method the background worker performs you would have something like:

    vb Code:
    1. Public Function (path as string) As Boolean 'don't know what you want to return.
    2.  
    3. // work done
    4.  
    5. Dim d as new Del_AddListBoxItem(AddressOf formAddListBoxItem)
    6. Me.Invoke(d, new object(){"testItem"})
    7. End Function

    You'll have to have a Public or Private Sub called 'myAddListBoxItem'.

    Would look something like:

    vb Code:
    1. Private Sub myAddListBoxItem(value as string)
    2.  
    3. Me.ListBox1.Items.Add(value)
    4.  
    5. End Sub

    Basically this is required when you are trying to update a GUI control from a thread other than the one
    the form was created on.

    Justin
    I did as you say now...im not getting anymore errors but the listbox is not getting updated

    Hmm...any ideas? As you asked....i'm running .RunWorkerAsync() in a button_click sub

    I'm calling my public procedure in the .DoWork procedure od backgroundworker ...

    Quote Originally Posted by MattP View Post
    No idea what your code looks like.

    I'd suggest starting here: http://vbnotebookfor.net/2007/09/24/...rker-in-vbnet/
    I'll try to implement that example on my example, thanks.
    Thanks for helping me out.

  10. #10
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Backgroundworker with public function and listbox

    YourBackgroundWorker.ReportProgress lets you send ProgressPercentage and UserState to the YourBackgrounWorker_ProgressChanged event. From there you can update any controls on the UI.
    Ohhh, ok. I didn't know that. I'm used to using threads and I thought the idea behind updating UI controls would be the same.

    Thanks for the clarification,

    Justin
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Backgroundworker with public function and listbox

    It is very much the same. You can certainly raise events from any thread, but those events are on the thread that raised them. That's not so useful, since you need the UI thread to handle any control interactions. Therefore, you need the events to be raised on the UI thread. You can do that from a standard thread using .Post on the SynchronizationContext, but one of the reasons the BackGroundWorker was added was to make this easier to do. It raises the ProgressChanged (and one other) on the UI thread automatically, without needing to deal with invoking or SynchronizationContexts.

    It's good to know about the other stuff, but the BGW does simplify things by hiding that other stuff.
    My usual boring signature: Nothing

  12. #12
    Frenzied Member
    Join Date
    Feb 2008
    Location
    Texas
    Posts
    1,288

    Re: Backgroundworker with public function and listbox

    Yeah but if the background workerhas a built in event, it would make sense to use that. But I learnedsomething new : ). Is there an android app for this site?
    You down with OOP? Yeah you know me!
    MCAD and MCMICKEYMOUSE (vb.net)

    ----

    If it even kinda helps... rate it : )

    Edit a Multi-page .tif file and save.

  13. #13

    Thread Starter
    Hyperactive Member
    Join Date
    Aug 2008
    Posts
    353

    Re: Backgroundworker with public function and listbox

    Well, im able to do a simple background work as. All my previous attempts have failed, but your help is greatly appreciated!

    Code:
     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
            TestWorker.RunWorkerAsync()
        End Sub
    
        Private Sub TestWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles TestWorker.DoWork
            Dim i As Integer
            For i = 0 To 20
                TestWorker.ReportProgress(i)
            Next i
        End Sub
    
        Private Sub TestWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles TestWorker.ProgressChanged
            TextBox1.Text = e.ToString
        End Sub
    But in my public function where i have a, i add :

    Code:
    for i...
    
      try 
      myresult = "result string"
      form1.TestWorker.ReportProgress(i)
      catch
    
      end try
    
    next
    nothing happends
    Last edited by batori; Apr 19th, 2012 at 03:23 AM.
    Thanks for helping me out.

  14. #14
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Backgroundworker with public function and listbox

    form1 is almost certainly wrong. What that will do is use the default instance of the form. I have ranted on about the evils of the default instance so many times I don't feel like going into it again. By using form1, in this case, you are doing that action on a very specific instance of the form, which may not even be the instance that is visible, and it may not be the instance where the code is running.

    Try using Me rather than form1.
    My usual boring signature: Nothing

  15. #15
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Re: Backgroundworker with public function and listbox

    Have a look at the msdn documentation: http://msdn.microsoft.com/en-us/libr...undworker.aspx. There are a couple of example showing it in use. Pay attention to where ReportProgress is being called and how they do it.
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

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