(Discussion) BackGroundWorker, Thread safety and Task pipelining/parallelization
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3

Thread: (Discussion) BackGroundWorker, Thread safety and Task pipelining/parallelization

  1. #1
    Join Date
    Jun 2011
    Location
    Buenos Aires, Argentina
    Posts
    109

    Post (Discussion) BackGroundWorker, Thread safety and Task pipelining/parallelization

    Hi, I'm trying to have a BackGroundWorker do some stuff periodically and I'm having some doubts on how to correctly plan my software to make good use of the tools provided by VS and C#.

    This is the scenario:
    My software communicates with some hardware by USB.
    Every X time, it measures n number of points, obtains data, processes it, adds it to chartAreas and stores it in a SQL DB.

    What I do now is start a Timer to wait until X time has elapsed, then start with all the different (sequential) tasks. Start with point 1, have it's HW do what it has to do, meassure, collect the data, etc., move on to point 2, and so on until point n.

    This, however, could also be done with a BGW (BackGroundWorker), to avoid having a Timer doing all that stuff. timer interval is 100 msec and what I need to do takes maybe minutes. Not good for the Timer...
    Plus, the BGW can report progress. Now, some problems with that... BGW_DoWork() method cannot access the Windows Forms that my main GUI created, so I must tell BGW_ProgressChanged method what it has to update. I would have to provide info on chartArea, timeStamp and value for the (to be added) dataPoint.
    BGW.ReportProgress() method can report progress % and an object with user data. This (I guess) would be how I can send data between the threads, but would require that I create a new encapsulating class that contains the targeted chartArea and the data I'm going to add.
    I'm not particullary happy with that... I get this feeling I'm mixing stuff...?

    Once I get one BGW to do all the stuff I need to, would it be safe to split all the work into n BGWs and have each one do the necessary work for each point? They would be accessing the USB port and recieving data, etc. If thread safety works, each BGW should get it's turn to send/recieve data and I would save a lot of time since I would have divided my processing time by n.

    Some code that might help:
    Code:
    // Timer Tick. If the scheduled time to meassure has passed, start BGW
    private void MainTimer_Tick(object sender, EventArgs e)
    {
        TimeSpan remainingTime = ScheduledToMeassure - DateTime.Now;
        if (remainingTime.Ticks < 0) BackgroundWorker.RunWorkerAsync();
    }
    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        MeassurePoints();
    }
    private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // do things with e.UserState
    }
    private void MeassurePoints()
    {
        foreach (Point p in points)
        {
            // doStuff
            BGW.ReportProgress(%, object) // object should include chartArea reference and dataPoint values (X, Y)
        }
    }
    What would be the best way to define my classes/methods/objects so that interaction between them is as optimal, simple and safe as possible?
    I'll be happy to fill in any other information/concepts you might need. Considering the nature of the post, I guess there will be a lot of that =)

    Thanks for reading!

  2. #2
    Join Date
    Dec 2011
    Posts
    61

    Re: (Discussion) BackGroundWorker, Thread safety and Task pipelining/parallelization

    MSDN has an article on how to access your winform controls in a thread-safe way. Code is like this:
    Code:
    delegate void setTextCallback(string text);
    
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        //do sth.
       setText("hello world");
    }
    
            private void setText(string text)
            {
                if (this.textBox1.InvokeRequired)
                {
                    setTextCallback callback = new setTextCallback(setText);
                    this.Invoke(callback, new object[] { text });
                }
                else
                {
                    this.textBox1.Text = text;
                }
            }
    Hope it helps.

  3. #3
    Join Date
    Jun 2011
    Location
    Buenos Aires, Argentina
    Posts
    109

    Re: (Discussion) BackGroundWorker, Thread safety and Task pipelining/parallelization

    Hi, yes, I am aware of that article on Thread-safe calls and have read it through. What you mention is the part specifically for BGW use. I could do that, but it would involve mayor changes I (think) should avoid.

    The chartArea I'd be accessing is actually part of a class that will update it when it's data is.

    I have a myOwnPointClass.Add(data) method, which then updates its private graphic objects according to the new data. So, resuming, I don't really have direct access to the object. I could of course rewrite the class to allow access, but I don't think it would be good programming. How can I check for invocation requirements from outside the class?

    In any case, what MSDN says conflicts sometimes. If you take a look at the documentation on BackGroundWorker there is a big note saying:

    "You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events."

    From that same article, and related to the parallelization I mention in my first post, I think it would be easier to have multiple BGWs doing stuff, and having the e.Result variable set in each BGW_DoWork() Method, so that the BGW_RunWorkerCompleted() method can do what it has to do. This way I could fire all async workers at once and have them do all the work. This, however, would still require that I encapsulate a reference to the point being meassured, the values red and other info I need in a new class to be able to assign to e.Result, which I'm not particulary happy about.

    Thanks for the help anyway!! =)

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
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center