Page 2 of 3 FirstFirst 123 LastLast
Results 41 to 80 of 91

Thread: Using the BackgroundWorker Component

  1. #41
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Using the BackgroundWorker Component

    well, for starters, your addhandlers for the progress change and completed events should be set BEFORE invoking the thread.
    Also... what does the search function do? And what do you have in your ProgressChanged and RunWorkerCompleted event handlers?

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  2. #42
    Hyperactive Member
    Join Date
    Nov 2008
    Location
    USA
    Posts
    257

    Re: Using the BackgroundWorker Component

    Ok thanks, I will move the addhandlers. The search function begins by calling
    the main in my discover class which then creates threads to read in urls which each then crawls and parses and adds to a database. Pretty involved function from there which I am carefully stepping through now.

    Code:
    Private Sub Search(ByVal sender As Object, ByVal e As DoWorkEventArgs)
                Dim BlogDiscoverObj As New SearchBlogDiscovery.BlogDiscover
                Dim reply As String = Nothing
                Dim errormessage As String = Nothing
    
                Application.DoEvents()
                Try
                    Console.WriteLine()
                    Console.WriteLine()
                    Console.Write(Thread.CurrentThread.Name & " ...searching " &   vbNewLine)
                    BlogDiscoverObj.Main(connectionString, userAgent, fileName, clientName, clientProj)
                    Dim i As Integer
                    For i = 1 To 100
                        CType(sender, BackgroundWorker).ReportProgress(i)
                        Thread.Sleep(100)
                    Next
                    Console.ResetColor()
                    Console.Write("Search Complete, Do you wish to generate queries, y or n? ")
                    reply = Console.ReadLine()
                    If reply = "y" Then
                        report()
                    ElseIf reply = "n" Then
                        Console.Clear()
                        main()
                    End If
                Catch ex As Exception
                    errormessage = ex.Message
    
                End Try
            End Sub

    my backgroundworker progress functions just have messages to the console to indicate what thread is doing...

    Code:
    Private Sub ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
                Console.WriteLine("Percent Complete: " & e.ProgressPercentage)
    
            End Sub
            Private Sub RunWorkerComplete(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
                Console.WriteLine("Background worker completed.")
            End Sub
    Thank you for your response.
    -- Please rate me if I am helpful --

  3. #43
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Using the BackgroundWorker Component

    you're doing user interaction in your threads:
    Code:
                    Console.ResetColor()
                    Console.Write("Search Complete, Do you wish to generate queries, y or n? ")
                    reply = Console.ReadLine()
    Which defeats the purpose... running backgroundthreads should be standalone... and shouldn't be directly interacting with the user...

    Your use of the progress changed is useless too, since the query is already done by the time you fake the loop.

    also, is this an attempt to "restart" the application?:
    Code:
                    ElseIf reply = "n" Then
                        Console.Clear()
                        main()
    Because if it is, you've just called your main function from inside your background thread....

    It doesn't surprise me that it quits after a while... I'm surprised it isn't more catastrophic.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  4. #44
    Hyperactive Member
    Join Date
    Nov 2008
    Location
    USA
    Posts
    257

    Re: Using the BackgroundWorker Component

    Thanks again...always helpful

    I have removed all user interaction from the search function ( backgroundworker process) and checked other functions too, and assume that console error messages are ok. You mentioned that the progress changed event is used incorrectly so where would I insert that? I just need to be able to track the bgw so I can trace the process for errors. Pardon me for taking up much of your time, but dearly appreciated. I will make the changes and run it but apart from what you have noted, do you think that considering the design and intent of my app, am I at least headed in the right direction?
    -- Please rate me if I am helpful --

  5. #45
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Using the BackgroundWorker Component

    hard to say... in this case, I wouldn't even bother with the progress changed event. create the thread, wire up the completed event, fire it off and let it do it's thing... when it's done, it fires off the completed event, and from there you do what ever cleanup you need to do... even if it's firing off a new thread (which, yes, you can do, we do that here to string together multiple BGW to pull data.)

    As for tracking errors... in the event of an error, you should be aborting the thread, which will cause the completed event to fire (in theory... I've heard rumors that it's not entirely reliable for some reason)... which will then have the aborted flag set to true. the reason I said the progress change is being misused is because it's a fake loop that's done after the search is done... so the progress it's reporting is junk, and you're sleeping the thread, which slows it down, and generally the purpose for BG Threads is to let time consuming processes a chance to run with out interefereing with the main thread... the sleep negates that.

    I don't know enough about what you are doing, but the way I would do it, is to create a class that holds the parameters needed to call the main funciton in your other class.... create an instance of it, fill it in, create a BGW, set the appropriate call backs, set the class as the parameter to the BGW and call the runasynch method. the run method then unpacks the parameter class, gets the data from it, creates the BlogDiscoverObj object, and calls the appropriate method. When it's done, set the object to nothing, sets up the return values, and then declares itself done.

    I'm reviewing past threads and I'm not sure what gain you are getting with using the BGW either... It looks like you're using threads for the sake of using them. if you were doing some kind of looping and running several searches simultaneously, then maybe... but it looks pretty sequential to me.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  6. #46
    Hyperactive Member
    Join Date
    Nov 2008
    Location
    USA
    Posts
    257

    Re: Using the BackgroundWorker Component

    I'm gonna go through this and see if I can implement it using this logic

    I don't know enough about what you are doing, but the way I would do it, is to create a class that holds the parameters needed to call the main funciton in your other class.... create an instance of it, fill it in, create a BGW, set the appropriate call backs, set the class as the parameter to the BGW and call the runasynch method. the run method then unpacks the parameter class, gets the data from it, creates the BlogDiscoverObj object, and calls the appropriate method. When it's done, set the object to nothing, sets up the return values, and then declares itself done.
    But the objective of my app is to provide the user the following options:
    1 - load a file to perform a search and let it run, the file can have up to 1 million urls.

    2 - query the database with options to select items the user needs and return items instantly to the output window or to an output file


    3 - perform a single url search by entering a single url


    this is why I am using threads or bgw to perform option # 1 and then implement later # 3.

    I already have threads doing the url fetching and that works fine except for some synchronizing for the outputs I will figure out. But again you have been very helpful and I just wanted to make the context of the app clearer.
    -- Please rate me if I am helpful --

  7. #47
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Using the BackgroundWorker Component

    Right... I get all that... but since it's a console app... it's not like the user can do anything else (like they would in a windows based app) and the UI isn't getting locked up (like it would in a windows app) ... so there isn't any benefit gain from using the BGW.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  8. #48
    Hyperactive Member
    Join Date
    Nov 2008
    Location
    USA
    Posts
    257

    Resolved Re: Using the BackgroundWorker Component

    Sorry tg...I am required to migrate this to a forms app after I can effectively display the concurrent execution of the two main processes i.e search and queries..

    In fact I have done the forms version first in what I would call beta version and I did not even use the bgw. Just called a new form when I needed to do option 2. Why they want me to do it this way...who knows???
    but my sups argument is that this app will be migrated later and he wants the performance evaluated. So...thanks for all your time and assistance...
    -- Please rate me if I am helpful --

  9. #49
    Member
    Join Date
    Apr 2006
    Posts
    41

    Re: Using the BackgroundWorker Component

    Sir,

    Is it also possible if I trigger the .RunWorkerAsync() in the Timer event?

    The idea is the event in the Do_Work automatically runs time to time..

    Thanks. =)

  10. #50

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by red7 View Post
    Sir,

    Is it also possible if I trigger the .RunWorkerAsync() in the Timer event?

    The idea is the event in the Do_Work automatically runs time to time..

    Thanks. =)
    What happened when you tried? If it worked then you have your answer. If it failed then you need to tell us what happened so we can diagnose the issue.

  11. #51
    Member
    Join Date
    Apr 2006
    Posts
    41

    Re: Using the BackgroundWorker Component

    It Worked! ^_^ Thanks.

  12. #52

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by red7 View Post
    It Worked! ^_^ Thanks.
    Cool. If it's feasible to do so, always try for yourself first. Developing a "look first, ask questions later" attitude is important to becoming a good developer.

  13. #53
    New Member
    Join Date
    Sep 2009
    Posts
    14

    Re: Using the BackgroundWorker Component

    not %100 sure this is the place for this - its a question about using the BackgroundWorker that is part of a class, not a form.



    i have a class the processes a general tasks, ClassA. it decides, based on info passed to it, which specific routine will handle this task.

    i have another class that processes specific tasks and has functions that are called to handle the task. call it ClassB.ProcessJobFunction()

    this works fine, but this process can take a long time and i need to have a Form object display the current status ("processing item X of Y")

    all of the examples of the BackgroundWorker use the BW as component on a form - in my case, i need it to be a member of my ClassA.

    so when ClassA is told to process a job, it
    1) creates a backgroundworker to process the job
    2) creates a new Form object to display the current tasks progress
    3) receives notifications from ClassB.ProcessJobFunction()as progress is made
    - i had thought to have this function raise an event?
    4) update the Form / UI

    i tried using threading but it doesn't seem like the right tool. BW does seem like the right tool but i am unclear if what i want is possible with it.

    any feedback would be appreciated.
    Last edited by Roccoman; Aug 24th, 2010 at 04:15 PM.

  14. #54
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Using the BackgroundWorker Component

    using the BW IS threading... so it's either the right tool, or it isn't, but not both. The BW has a ProgressChange event that you can handle. That event would get raised on the UI thread, where you would then be able to update the display as needed. You can invoke the event when you want by calling .UpdateProgress method (I think that's right) from inside your process.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  15. #55
    New Member
    Join Date
    Sep 2009
    Posts
    14

    Re: Using the BackgroundWorker Component

    thanks for the quick response techgnome

    yea i worded that badly - BW is threading of course. i was refering to using either a Thread object or a BW object.

    anyway i think i have found a suitable solution in the most unlikely of places: vb6 and DoEvents

    i had forgotten that this was still in VB.NET (under My.Application and was reminded by a co-worker)

    this allows the progress form to be updated and responsive to the user within the function ClassB.ProcessJobFunction() - and each thread has its own form so (in theory) there should be no cross-thread issues.

    thanks

  16. #56
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: Using the BackgroundWorker Component

    The BW is simply a wrapper around the threading class... just depends on how much you want to black box (the BGW will hide some extraneous plumbing while dealing with the thread directly will give you finer control)...

    DoEvents.... Hmmm.... I'm not sure how I feel about that. It has its uses in VB6 mainly because VB6 didn't support threading. Which .NET does. Just because you CAN doesn't mean you SHOULD. I CAN shoot my foot with a gun... doesn't mean it's a good idea.

    Each thread my have it's own form... but if I remember right, the process is still only going to have ONE UI thread... which means those extra forms may still be on the original thread. Point being, I don't think you're out of the woods.

    I'm not sure where the problem is. What you're doing is extremely typical and precisely what the BGW was designed for. That's why it has a ProgressChanged even that even includes the PercentCompleted in the event args. All you need to do it set the value and call the ProgressChanged method. Then let the parent UI safely handle the UI update.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  17. #57
    New Member
    Join Date
    Sep 2009
    Posts
    14

    Re: Using the BackgroundWorker Component

    the way i wrote the ClassA object it has a private member FormWait that is the progress form for that particular job.

    there is a main form for the application but it is not the one that needs to be updated during the process - ClassA shows its own FormWait at the beginning of its processing and unloads it at the end.


    i suppose the question is this: if i start a new thread (via a delegate subroutine) and that routine creates a new instance of a form, is that form in the new thread or the UI thread?

    btw - i have run this a number of times now and so far have no cross-thread issues with the forms (other code is raising the issue, but that is due to shared functions being called)

    anyway i truly do appreciate the responses - i am a new to threading and although devouring MSDN's Help system is useful, hearing from people who really use these tools helps a ton more.
    Last edited by Roccoman; Aug 24th, 2010 at 08:35 PM.

  18. #58

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Forms aren't "in" any particular thread. Just like all data, a form is accessible on all threads. The issue is that the handle of any control including a form, has an affinity for the thread it was created on. That means that whatever thread creates the control owns the handle, which means that it's only safe to access members of that control, other than Invoke and the like, on that thread.

    If you want to display a "Please Wait..." message to the user while a background operation takes place then I consider the best way to be as follows:

    1. Display a form, modal or not, on the UI thread. The form should provide no interface for closing it, other than a Cancel button if the operation can be cancelled.
    2. Start a secondary thread, either explicitly or using a BackgroundWorker, in that form's Load or Shown event handler.
    3. When the secondary thread completes, close the form.

  19. #59
    New Member
    Join Date
    Sep 2009
    Posts
    14

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by jmcilhinney View Post
    Forms aren't "in" any particular thread. Just like all data, a form is accessible on all threads. The issue is that the handle of any control including a form, has an affinity for the thread it was created on. That means that whatever thread creates the control owns the handle, which means that it's only safe to access members of that control, other than Invoke and the like, on that thread.

    If you want to display a "Please Wait..." message to the user while a background operation takes place then I consider the best way to be as follows:

    1. Display a form, modal or not, on the UI thread. The form should provide no interface for closing it, other than a Cancel button if the operation can be cancelled.
    2. Start a secondary thread, either explicitly or using a BackgroundWorker, in that form's Load or Shown event handler.
    3. When the secondary thread completes, close the form.
    thats the problem - i need it to be the opposite. i need my function to control its own form (as there can be multiple threads running at the same time, each with their own FormWait form)

    perhaps my design is wrong in this.

    you solution would work for me but would require a bit of re-work.

    thanks for the feedback!
    Last edited by Roccoman; Aug 24th, 2010 at 08:54 PM.

  20. #60

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by Roccoman View Post
    thats the problem - i need it to be the opposite. i need my function to control its own form (as there can be multiple threads running at the same time, each with their own FormWait form)
    I doubt that you do. What I described is most likely fine. You should be able to show multiple forms on the UI thread and then have each of those start its own secondary thread. Try the attached example.
    Attached Files Attached Files

  21. #61
    New Member
    Join Date
    Sep 2009
    Posts
    14

    Re: Using the BackgroundWorker Component

    thanks Jmc - i'll take a look a your sample
    Last edited by Roccoman; Aug 25th, 2010 at 02:55 PM. Reason: cuz i am a space cadet

  22. #62
    Frenzied Member
    Join Date
    Aug 2009
    Location
    Los Angeles
    Posts
    1,335

    Re: Using the BackgroundWorker Component

    I have the following Sub that performs a couple of loops through a datatable . I currently have a progressbar1 that works fine, however while the sub is running if the user clicks on anything the progress bar and label freeze, the sub is still running and every functions fine. SO would I be correct in assuming this is a situation for backgroundworker? and have the label and progressbar woking on there own thread??

    If so I am not sure how to implement it with my sub?? I am trying to follow and learn from the example you posted. I built the sample and trying to see how my code would be implemented.

    I placed my Sub "GetValue()" in the BGW do work event but thats obviously not correct because that would just a one time event

    I think I need to capture the first loop of that Sub

    For i As Integer = 0 To dtlist.Rows.Count - 1
    Dim lat As Double = CDbl(dtlist.Rows(i)("Latitude"))
    Dim lon As Double = CDbl(dtlist.Rows(i)("Longitude"))


    vb Code:
    1. Dim Coords() As Coord = GetCoords()
    2.         Dim sw As Stopwatch
    3.         sw = Stopwatch.StartNew
    4.         Me.propsprocessed.Visible = True
    5.         Me.lblCount.Visible = True
    6.         Me.ProgressBar1.Visible = True
    7.  
    8.         For i As Integer = 0 To dtlist.Rows.Count - 1
    9.             Dim lat As Double = CDbl(dtlist.Rows(i)("Latitude"))
    10.             Dim lon As Double = CDbl(dtlist.Rows(i)("Longitude"))
    11.             'Labelcount
    12.             Me.lblCount.Text = CStr(i + 1)
    13.             Me.lblCount.Refresh()
    14.             'progress bar
    15.             ProgressBar1.Maximum = dtlist.Rows.Count
    16.             ProgressBar1.Minimum = 0
    17.             For d = ProgressBar1.Minimum To ProgressBar1.Maximum
    18.                 ProgressBar1.Value = i
    19.             Next
    20.             For t As Integer = 0 To dtsold.Rows.Count - 1
    21.                 dtsold.Rows(t)("Distance") = (DistanceCalc1(lat, lon, Coords(t).Lat1, Coords(t).Lon1, CChar("M")))
    22.             Next
    23.             Dim Dt As Decimal = NumericUpDown1.Value
    24.             dtlist.Rows(i)("Value") = dtsold.Compute("Max(ClosePrice)", "Distance <=" & Dt & "")
    25.  
    26.         Next
    27.         ProgressBar1.Visible = False
    28.         sw.Stop()
    29.         Dim StopWatchString As String
    30.         StopWatchString = "Processing Time = " & sw.ElapsedMilliseconds & " milliseconds"
    31.  
    32.         Dim ts As String = CStr(sw.Elapsed.Minutes)
    33.         ElapsedTime.Text = "In" & " " & ts & " " & "Seconds"
    34.         ElapsedTime.Show()

    If someone can give me some guideanceiwold appreciate it

    Thanks

  23. #63

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    @billboy: It's very simple. You perform the long-running task in the DoWork event handler. If the long-running task is an entire loop then you put the entire loop in the DoWork event handler. If you need to update the UI during the task then you call ReportProgress and handle the ProgressChanged event. If you need to update the UI after the task then you handle the RunWorkerCompleted event. That's really all there is to it.

  24. #64
    Frenzied Member
    Join Date
    Aug 2009
    Location
    Los Angeles
    Posts
    1,335

    Re: Using the BackgroundWorker Component

    I think I am a bit closer

    getting error:
    An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll

    Additional information: Exception has been thrown by the target of an invocation.

    I put the task in the DoWorkEvent

    vb Code:
    1. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    2.         Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
    3.         Dim Coords() As Coord = GetCoords()
    4.         Dim sw As Stopwatch
    5.         sw = Stopwatch.StartNew
    6.  
    7.         For i As Integer = 0 To dtlist.Rows.Count - 1
    8.             Dim lat As Double = CDbl(dtlist.Rows(i)("Latitude"))
    9.             Dim lon As Double = CDbl(dtlist.Rows(i)("Longitude"))
    10.             worker.ReportProgress(i)
    11.  
    12.             For t As Integer = 0 To dtsold.Rows.Count - 1
    13.                 dtsold.Rows(t)("Distance") = (DistanceCalc1(lat, lon, Coords(t).Lat1, Coords(t).Lon1, CChar("M")))
    14.             Next
    15.             Dim Dt As Decimal = NumericUpDown1.Value
    16.             dtlist.Rows(i)("Value") = dtsold.Compute("Max(ClosePrice)", "Distance <=" & Dt & "")
    17.  
    18.         Next

    The error comes up at the last line, what am I missing/doing wrong?

  25. #65

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    @billboy:

    First things first, what's this doing in your DoWork event handler?
    Code:
    Dim Dt As Decimal = NumericUpDown1.Value
    A NumericUpDown is a control. No accessing controls in the DoWork event handler.

    As for the error, that's the exception you see on the UI thread when an exception is thrown on a secondary thread. You need to catch the exception on the secondary thread, examine it and fix the issue that's causing it, just as you would do on the UI thread.

  26. #66
    Frenzied Member
    Join Date
    Aug 2009
    Location
    Los Angeles
    Posts
    1,335

    Re: Using the BackgroundWorker Component

    Oh missed that NumericUpDown I took that out and hard coded my distance for now

    As for catching the exception, I am not sure how to do that. The same code runs fine when not implementing backgroundworker

    try
    Catch ??

    My Values are returned
    Last edited by billboy; Jun 3rd, 2011 at 11:48 PM.

  27. #67

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by billboy View Post
    Oh missed that NumericUpDown I took that out and hard coded my distance for now

    As for catching the exception, I am not sure how to do that. The same code runs fine when not implementing backgroundworker

    try
    Catch ??

    My Values are returned
    There's only one way to catch an exception, and that's with a Catch statement.

  28. #68
    Frenzied Member
    Join Date
    Aug 2009
    Location
    Los Angeles
    Posts
    1,335

    Re: Using the BackgroundWorker Component

    Thats what I thought, I am not getting a message though?

    vb Code:
    1. Try
    2.             For i As Integer = 0 To dtlist.Rows.Count - 1
    3.                 Dim lat As Double = CDbl(dtlist.Rows(i)("Latitude"))
    4.                 Dim lon As Double = CDbl(dtlist.Rows(i)("Longitude"))
    5.                 worker.ReportProgress(i)
    6.                 'Labelcount
    7.                 For t As Integer = 0 To dtsold.Rows.Count - 1
    8.                     dtsold.Rows(t)("Distance") = (DistanceCalc1(lat, lon, Coords(t).Lat1, Coords(t).Lon1, CChar("M")))
    9.                 Next
    10.                 'Dim Dt As Decimal = NumericUpDown1.Value
    11.                 dtlist.Rows(i)("Value") = dtsold.Compute("Max(ClosePrice)", "Distance <=.5")
    12.             Next
    13.         Catch exc As Exception
    14.             MessageBox.Show(exc.Message & vbCrLf & vbCrLf & exc.StackTrace, exc.GetType().ToString())
    15.         End Try

    Also tried it here:

    vb Code:
    1. Private Sub GetValue()
    2.         Try
    3.             Me.propsprocessed.Visible = True
    4.             Me.lblCount.Visible = True
    5.             Me.ProgressBar1.Visible = True
    6.             Me.BackgroundWorker1.RunWorkerAsync()
    7.         Catch exc As Exception
    8.             MessageBox.Show(exc.Message & vbCrLf & vbCrLf & exc.StackTrace, exc.GetType().ToString())

    And here:


    vb Code:
    1. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GetValues.Click
    2.         Try
    3.             GetValue()
    4.         Catch exc As Exception
    5.             MessageBox.Show(exc.Message & vbCrLf & vbCrLf & exc.StackTrace, exc.GetType().ToString())
    6.         End Try
    7.     End Sub

  29. #69
    Frenzied Member
    Join Date
    Aug 2009
    Location
    Los Angeles
    Posts
    1,335

    Re: Using the BackgroundWorker Component

    Ok I still dont understand why my exception message box doesnt appear, but I managed to view the debug out window and found the error, i needed to set my progressbar maximum state

    ProgressBar1.Maximum = dtlist.Rows.Count

    I know I still have some problems, with access control textbox etc... but I think you have given me enough insight to tackle rest for now....

    Thanks

  30. #70
    New Member
    Join Date
    May 2012
    Posts
    2

    Re: Using the BackgroundWorker Component

    Hi,

    Sorry for dragging this post back up but its the best example I found.

    I'm also a bedroom hobbyist and therefore don't have any real expirence in programming so forgive me for if this is a dumb question.

    I have a background worker within my form and a progress bar which works fine whilse the work being carried out is within the same form. If I move the work to a Module the work still gets carried out but my progress bar doesn't update anymore. My understanding is this is because the work and progress bar are not within the same ui thread but I dont understand how to fix this issue.

    Here's a quick example of a test I setup...

    My Main Form

    Code:
    Public Class Form_Test
    
        Delegate Sub SetLabelText_Delegate(ByVal Label As Label, ByVal [text] As String)
    
        Public Sub SetLabelText_ThreadSafe(ByVal Label As Label, ByVal [text] As String)
    
            If Label.InvokeRequired Then
                Dim MyDelegate As New SetLabelText_Delegate(AddressOf SetLabelText_ThreadSafe)
                Me.Invoke(MyDelegate, New Object() {Label, [text]})
            Else
                Label.Text = [text]
            End If
    
        End Sub
    
        Public Sub test()
    
            Dim i As Integer = 0
    
            Do While i < 20
    
                i = i + 1
    
                Me.BackgroundWorker1.ReportProgress(CInt((i / 20) * 100))
                Me.SetLabelText_ThreadSafe(Label1, "Same Form - " & FormatPercent(i / 20, 0))
    
                System.Threading.Thread.Sleep(100)
    
                Debug.Print("Running Test 2 From Within The Same Form: " & i)
            Loop
    
        End Sub
    
        Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    
            Me.ProgressBar1.Value = e.ProgressPercentage
    
        End Sub
    
        Private Sub BackgroundWorker1_DoWork_1(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    
            test()
    
        End Sub
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    
            Me.BackgroundWorker1.RunWorkerAsync()
    
        End Sub
    
        Private Sub BackgroundWorker2_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker2.ProgressChanged
    
            Me.ProgressBar1.Value = e.ProgressPercentage
    
        End Sub
    
        Public Sub BackgroundWorker2_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker2.DoWork
    
            test_2()
    
        End Sub
    
        Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    
            Me.BackgroundWorker2.RunWorkerAsync(2)
    
        End Sub
    
    End Class
    My Module Code

    Code:
    Module Module_Test
    
        Public Sub test_2()
    
            Dim i As Integer = 0
    
            Do While i < 20
    
                i = i + 1
    
                Form_Test.BackgroundWorker1.ReportProgress(CInt((i / 20) * 100))
                Form_Test.SetLabelText_ThreadSafe(Form_Test.Label1, "Module - " & FormatPercent(i / 20, 0))
    
                System.Threading.Thread.Sleep(100)
    
                Debug.Print("Running Test 2 From Within A Module: " & i)
    
            Loop
    
        End Sub
    
    End Module
    Anyone got any suggestions?

    Many Thanks

    Ben

  31. #71

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    @jaminben, the work is carried out on a different thread to the one that owns the ProgressBar in both cases. That's the whole point. The issue is related to your use of a default instance. Follow the Blog link in my signature and check out my post on Default Form Instances to learn how they work and don't work. That should help to explain what you're doing wrong. If you still need help to fix it, post back.

  32. #72
    New Member
    Join Date
    May 2012
    Posts
    2

    Re: Using the BackgroundWorker Component

    Can you throw me a bone (I've read through your blog, as well as others)... And I'm not really understanding instances and how you reference between them with the background worker.

    Thanks

    Edit

    Not too worry I worked it out... thanks for the push in the right direction though
    Last edited by jaminben; May 15th, 2012 at 10:46 AM.

  33. #73
    Member
    Join Date
    Jun 2008
    Location
    Melbourne, Australia
    Posts
    37

    Re: Using the BackgroundWorker Component

    Thanks a lot. Great post!

  34. #74
    Fanatic Member BenJones's Avatar
    Join Date
    Mar 2010
    Location
    Wales UK
    Posts
    629

    Re: Using the BackgroundWorker Component

    Thanks for shareing jmcilhinney, I not looked at the background worker, but your examples should help me a lot thanks agian.

  35. #75
    Addicted Member
    Join Date
    Dec 2011
    Posts
    194

    Re: Using the BackgroundWorker Component

    How can i access one or more control from DoWork event
    vb Code:
    1. Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    2.  
    3.         Dim strLines() As String = IO.File.ReadAllLines("some_path")
    4.         Dim intLength As Integer = strLines.Length - 1 ' This will not less than 50,000
    5.         Dim f() As String
    6.  
    7.         For j As Integer = 0 To intLength
    8.             f = strLines(j).Split("|")
    9.             ListView1.Items.Add(f(0))
    10.             ListView2.Items.Add(f(1))
    11.         Next
    12.  
    13.     End Sub

  36. #76

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by Absolute_Zero View Post
    How can i access one or more control from DoWork event
    You can't. That's what the ProgressChanged and RunWorkerCompleted events are for? Did you actually read any of my posts?

  37. #77
    Freelancer akhileshbc's Avatar
    Join Date
    Jun 2008
    Location
    Trivandrum, Kerala, India
    Posts
    7,652

    Re: Using the BackgroundWorker Component

    jm, all controls are in the UI thread. And thus, we can't access it from the BackgroundWorker's DoWork event, which runs in a separate thread.

    But the variables inside that form(class level scope) is accessible inside it. Isn't it ?
    I just tried it by declaring a class level array and inside the DoWork, I have returned the length of the array.
    So, any variables declared in that current form is accessible, right?

    Or that's not the best approach? I should always pass the values to it as a parameter of RunWorkerAsync() ?

    Thanks

    If my post was helpful to you, then express your gratitude using Rate this Post.
    And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video)
    My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet

    Social Group: VBForums - Developers from India


    Skills: PHP, MySQL, jQuery, VB.Net, Photoshop, CodeIgniter, Bootstrap,...

  38. #78

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by akhileshbc View Post
    jm, all controls are in the UI thread. And thus, we can't access it from the BackgroundWorker's DoWork event, which runs in a separate thread.

    But the variables inside that form(class level scope) is accessible inside it. Isn't it ?
    I just tried it by declaring a class level array and inside the DoWork, I have returned the length of the array.
    So, any variables declared in that current form is accessible, right?

    Or that's not the best approach? I should always pass the values to it as a parameter of RunWorkerAsync() ?

    Thanks
    You're confusing two unrelated things. The DoWork event handler of the BackgroundWorker is a method like any other other method. It is a member of the form like any other form. It has all the same rights and privileges as any other method in the form. Member variables are within the scope of the form so any methods within that form can access those methods.

    You can even write code in that method to access the controls on the form and the compiler will not complain as long as the syntax is correct. If you were to call that method directly then the code would work fine. It's only if, at run time, a method is run on a secondary thread that any control access that uses the Handle will fail. That's a run time issue, not a design time issue.

  39. #79
    Freelancer akhileshbc's Avatar
    Join Date
    Jun 2008
    Location
    Trivandrum, Kerala, India
    Posts
    7,652

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by jmcilhinney View Post
    You're confusing two unrelated things. The DoWork event handler of the BackgroundWorker is a method like any other other method. It is a member of the form like any other form. It has all the same rights and privileges as any other method in the form. Member variables are within the scope of the form so any methods within that form can access those methods.

    You can even write code in that method to access the controls on the form and the compiler will not complain as long as the syntax is correct. If you were to call that method directly then the code would work fine. It's only if, at run time, a method is run on a secondary thread that any control access that uses the Handle will fail. That's a run time issue, not a design time issue.
    Means, the methods that access the controls can't be called inside the DoWork() as well as no controls can be accessed directly within that event.
    Because, the code inside the DoWork() event executes in a separate thread and the controls are in another thread.

    But all other variables/methods can directly be accessed within in it.

    Am I correct ?

    Thanks

    EDIT:
    jm, I am still confused(even after reading the below post). So, I will try to refresh my brain by reading again topics about Threading and thread affinity. And will create a thread in VB.Net forum, instead of flooding this thread Thanks again.
    Last edited by akhileshbc; Jul 26th, 2012 at 01:16 AM. Reason: -- @ JM --

    If my post was helpful to you, then express your gratitude using Rate this Post.
    And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video)
    My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet

    Social Group: VBForums - Developers from India


    Skills: PHP, MySQL, jQuery, VB.Net, Photoshop, CodeIgniter, Bootstrap,...

  40. #80

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,297

    Re: Using the BackgroundWorker Component

    Quote Originally Posted by akhileshbc View Post
    Means, the methods that access the controls can't be called inside the DoWork() as well as no controls can be accessed directly within that event.
    Because, the code inside the DoWork() event executes in a separate thread and the controls are in another thread.

    But all other variables/methods can directly be accessed within in it.

    Am I correct ?

    Thanks
    No you're not correct. Controls are accessed via member variables too. All members are accessible from all other members. Accessing a control in the DoWork event handler is allowed. The compiler will not complain. At run time though, those accesses that are performed via legal code will fail. They are two different concepts: scope and thread affinity.

Page 2 of 3 FirstFirst 123 LastLast

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