Results 1 to 9 of 9

Thread: [RESOLVED] Seeking advice: BackGroundWorker or Task

  1. #1

    Thread Starter
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Resolved [RESOLVED] Seeking advice: BackGroundWorker or Task

    Presently I'm using BackGroundWorker(s) to do calculations which may take a long time (calculating a BackGroundImage, calculating the next simulation-step for objects ...). The result of each BGW is used whenever ready (i.e. if the information is used before ready/updated the older information is used).

    Should I better use Tasks in such a scenario?
    I far as I understand the documentation, I would expect a better performance using Tasks.

    I did some experimentation, however I can't seem to find the correct implementation in order to let the main process (the GUI) continue with waiting the Tasks to complete. Do I realy have to use the .Wait Method in order to get any result from my Task? Isn't there a way to get the results of a Task without .Wait (like an Event TaskCompleted)?
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

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

    Re: Seeking advice: BackGroundWorker or Task

    I've never done it myself but I believe that you can call ContinueWith on the Task and pass TaskContinuationOptions.ExecuteSynchronously as an argument. The continuation action will then be executed synchronously, i.e. on the UI thread, when the original asynchronous task has completed. That's much like the RunWorkerCompleted event handler of a BackgroundWorker.

    That said, if you're running this code inside a form then I'd stick to the BackgroundWorker. If it's in some other class that has no direct dependence on a UI then I'd switch to the TPL.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

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

    Re: Seeking advice: BackGroundWorker or Task

    I should stipulate that you don't have to wait until the original task has completed to call ContinueWith. You call ContinueWith when you create the Task and it then stores the provided delegate in the Task object, to be invoked implicitly when the task completes.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  4. #4

    Thread Starter
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Seeking advice: BackGroundWorker or Task

    Quote Originally Posted by jmcilhinney View Post
    I've never done it myself .....
    I didn't expect such a statement from you.

    Quote Originally Posted by jmcilhinney View Post
    That said, if you're running this code inside a form then I'd stick to the BackgroundWorker. If it's in some other class that has no direct dependence on a UI then I'd switch to the TPL.
    Yes, as of now I call those calculations (as BGW or Task) from the UI, so I'll stichk with BGW.
    However, since I'm looking to completly seperate the "simulation" for presentation on the UI I will also look into .ContinueWith.

    Thanks
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

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

    Re: Seeking advice: BackGroundWorker or Task

    Quote Originally Posted by opus View Post
    I didn't expect such a statement from you.
    I've done some cursory research into the TPL and have been meaning to do more for some time but haven't had a specific need yet so haven't got around to it.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  6. #6
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Seeking advice: BackGroundWorker or Task

    Since you seem to have a value that changes over time, you may want to investigate the Reactive framework.

    As to ContinuationOptions.ExecuteSynchronously, I'm not sure that's the one you want to use. As I recall, that continues on the same thread that the Task ran on. Instead, use TaskScheduler.FromCurrentSynchronizationContext to the scheduler parameter when on the UI thread (i.e. create the Task and attach the continuation at the same time, as jmc mentioned)

    If you have any interest in unit testing, I would strongly advise putting your own abstraction between your application and whatever libraries you use to implement this. (Both TPL and Rx have good APIs, so if you don't need to decouple for testing purposes then coding directly against their APIs is fine, their ability to allow unit tests to control the threading sucks big time though.)

  7. #7

    Thread Starter
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Seeking advice: BackGroundWorker or Task

    I've read on .ContinueWith, it sounds promissing, however what is the correct syntax??
    I'm using

    Code:
    Dim ChartTask = Task.Factory.StartNew(Sub() ChartWorks()) 'Chatworks is the sub that does the work(set a new BackGroundImage to a control)
    ChartTask.Wait 'Without thisOne I get no result
    I found no correct way to place .ContinueWith. "ChartTask.ContinueWith(TaskContinuationOption.ExecutesSynchronously)" is not accepted?
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

  8. #8
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Seeking advice: BackGroundWorker or Task

    You need to give it a continuation for it to continue with. This is where you're first seeing the very different nature of this style of programming. Your ChartWorks method needs to be split in two: one part that generates the image, another that updates the UI control. You then run the first part as a new task, and supply the second part as the continuation. You specify both things at the beginning, but the continuation won't run until the later.

    Here's a very noddy example. Note that you can click the button multiple times, and you'll get multiple updates as each of the tasks completes. There is NO error handling, normally you should attach continuations for error events using the TaskContinuationOptions enumeration and/or check the state of the Task in the continuation.

    vbnet Code:
    1. Public Class Form1
    2.  
    3.     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4.         Task.Factory.StartNew(AddressOf GenerateImage).ContinueWith(AddressOf UpdateBackground, TaskScheduler.FromCurrentSynchronizationContext())
    5.     End Sub
    6.  
    7.     Private colors() As Color = {Color.Red, Color.Green, Color.Blue}
    8.     Private currentColorIndex As Integer = 0
    9.  
    10.     Private Function GenerateImage() As Image
    11.         Dim index = currentColorIndex
    12.         currentColorIndex = currentColorIndex + 1
    13.         If currentColorIndex >= colors.Length Then
    14.             currentColorIndex = 0
    15.         End If
    16.  
    17.         Dim image As New Bitmap(100, 100)
    18.         Dim g = Graphics.FromImage(image)
    19.         g.FillRectangle(New SolidBrush(colors(index)), New Rectangle(New Point(2, 2), New Size(96, 96)))
    20.         g.Flush()
    21.  
    22.         Threading.Thread.Sleep(1000)
    23.         Return image
    24.     End Function
    25.  
    26.     Private Sub UpdateBackground(imageTask As Task(Of Image))
    27.         Panel1.BackgroundImage = imageTask.Result
    28.     End Sub
    29. End Class

  9. #9

    Thread Starter
    I don't do your homework! opus's Avatar
    Join Date
    Jun 2000
    Location
    Good Old Europe
    Posts
    3,863

    Re: Seeking advice: BackGroundWorker or Task

    Thank you very much.

    I got it working now for the BackGroundImage, although I had to build in a blocking mechanism (because ChartWorks needs access to files, and if you try to repaint the Background to fast those files would be read by several ChartWork Tasks).

    I'll do the same with my other routines, Thanks

    Yes, looking at it that way it is the same technique as using the BGW
    You're welcome to rate this post!
    If your problem is solved, please use the Mark thread as resolved button


    Wait, I'm too old to hurry!

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