Saturday 21 April 2012

Asynchronous methods in C#: Part II


Introduction
In this article we demonstrate how to report progress information and intermediate results from asynchronous method. This article builds on previous article, Asynchronousmethod in C#: Part I.

Using Code
In this article we do following changes in our previous example.

  • ·         Modify Perform method for reporting progress.
  • ·         Implement ProgressChanged event.
  • ·         Define method ReportProgrss that synchronizes Perform method and ProgressChanged event

Perform Method:
Here is a perform method that we define in our previous example.
        private void Perform(string[] files)
        {
            foreach (string file in files)
            {
                //do something......
                Thread.Sleep(100);
            }
        }
Now we modify it such way, that it reports progress of task to client code and processed files.
        private void Perform(string[] files)
        {
            int counter = 0;
            foreach (string file in files)
            {
                //do something......
                Thread.Sleep(100);

                counter++;
                int percentage = (100 * counter) / files.Length;

                ReportProgress(percentage, file);
            }
        }
After processing file, we compute percentage in percentage and paases it as an argument in ReportProgress() method, which is an example of how to pass intermediate result to client code.

ProgressChanged event:

This event raised whenever asynchronous method wants to report progress to client code.

        public event ProgressChangedEventHandler ProgressChanged
        {
            add
            {
                this.progressChangedEventHandler += value;
            }
            remove
            {
                this.progressChangedEventHandler -= value;
            }
        }
        private ProgressChangedEventHandler progressChangedEventHandler;

        protected virtual void OnProgressChanged(ProgressChangedEventArgs e)
        {
            if (progressChangedEventHandler != null)
                progressChangedEventHandler(this, e);
        }

Handling ProgressChanged event in client code:

Register and implement handler of ProgressChanged event.

        t.ProgressChanged += new ProgressChangedEventHandler(task_ProgressChange);

        static void task_ProgressChange(object sender, ProgressChangedEventArgs e)
        {
            System.Diagnostics.Debug.Print("[Task] Progress: {0} %, Current File: {1}", e.ProgressPercentage, e.UserState);
        }

ReportProgress method:

This method calls ProgressChanged event through AsyncOperation object.

        void ReportProgress(int percentProgress, object userState)
        {
            // FIXME: verify the expected behavior
            if (!IsBusy)
                return;

            async.Post(delegate(object o)
            {
                ProgressChangedEventArgs e = o as ProgressChangedEventArgs;
                OnProgressChanged(e);
            },
                new ProgressChangedEventArgs(percentProgress, userState));
        }


In this series
  1.  Asynchronous method in C#: Part - I 
  2. Asynchronous method in C#: Part - II.

No comments:

Post a Comment