Search code examples
c#multithreadingreportprogress

Report thread progress with a stage first approach


I'm willing to report the progress of an intensive task (I/O). I've been reading all the approaches, interface, backGroundWorker, Progress, but no one include any kind of additional info like the current stage of the task. So i wrote this approach and i will be happy if you can give me any kind of feedback, advice or a comment. I'm working in a winforms 4.0 project.

This is the task

   class _ThreadTest
        {
        public static  void ReporteProgreso(out int p, out string stage)
        {
            p = 0;
            stage = "";
            for (int i = 0; i < 10; i++)
            {

                System.Threading.Thread.Sleep(500);
                p++;

                switch (p)
                {
                    case 0: stage = "init"; break;
                    case 1: stage = "Loading Data"; break;
                    case 2: stage = "Parsing Data"; break;
                    case 3: stage = "Checking"; break;
                    case 4: stage = "Inserting n Records"; break;
                    case 5: stage = "10%"; break;
                    case 6: stage = "50%"; break;
                    case 7: stage = "70%"; break;
                    case 8: stage = "100%"; break;
                    case 9: stage = "finish"; break;                        

                    default:
                        break;
                }
            }

        }
    }

And here is how I call it

  static void Main()
        {

        //Reportar progreson con OUT
        int p = 0;
        string stage = "";
        _ThreadTest t = new _ThreadTest();
        Thread oThread = new Thread( () => _ThreadTest.ReporteProgreso(out p,out stage) ) ;
        oThread.Start();

        int tmp = 0;
        while (oThread.IsAlive)
        {

            if (tmp != p)
            {
                Console.WriteLine(stage);
                tmp = p;
            }
        }

        Console.ReadKey();

    }
}

Are there any interesting tested, better way to achieve this? Since this approach is working for me, maybe it will not be safe to use in some types of environments.


Solution

  • BackgroundWorker.ReportProgress does exactly what you're trying to do. The second parameter is an object that contains your custom progress report.

    That second parameter is in the UserState property in the ProgressChangedEventArgs that's passed to your ProgressChanged event handler.

    The BackgroundWorker MSDN topic has a pretty good example. The only thing missing in that example is how to use UserState. It's an object, so you need to cast it. So, if your ReportProgress call is:

    ReportProgress(1, "Loading data");
    

    Then in your ProgressChanged event handler, you'd cast it back to string:

    // This event handler updates the progress. 
    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        resultLabel.Text = (string)e.UserState
    }