Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Waiting for background thread pattern
Message
From
18/05/2011 13:22:40
 
 
To
18/05/2011 12:16:39
General information
Forum:
ASP.NET
Category:
Coding, syntax and commands
Environment versions
Environment:
C# 4.0
OS:
Windows XP SP2
Application:
Desktop
Miscellaneous
Thread ID:
01510997
Message ID:
01511011
Views:
44
>Have you looked at the new Asynch stuff? http://msdn.microsoft.com/en-us/vstudio/async.aspx
>
>>Hi all,
>>
>>I am making some changes to an application to help with performance. On the startup currently there are lots of objects and initialization that needs to be performed and currently this is blocking the UI thread. I am moving these things to a Background worker thread so the UI can continue to load and present. The question is I am looking for an appropriate pattern or design that I could implement to know if the user attempts something that requires the Background worker to be done before the worker is completed it would wait. This means either the worker is done and the user action could continue; or the user attempt is waited pending the completion of the worker thread. In addition, if the user exits, I would need to cancel the worker thread if it is still running.
>>
>>I have experimented with a couple of mechanisms but thinking there may already be some design pattern for this.
>>Thanks

Hi,
Don't know if there's a generally accepted pattern. In this situation I usually end up with something like:
using System;
using System.ComponentModel;

namespace ConsoleApplication6
{
    class Program
    {
        static bool ThreadCancelled = false;
        static SomethingTheWorkerBuilds theResult;
        static void Main(string[] args)
        {
            BackgroundWorker bg = new BackgroundWorker();
            bg.WorkerSupportsCancellation = true;
            bg.WorkerReportsProgress = true;
            bg.DoWork += new DoWorkEventHandler(bg_Work);
            bg.ProgressChanged += new ProgressChangedEventHandler(bg_ProgressChanged);
            bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
            bg.RunWorkerAsync();
            System.Threading.Thread.Sleep(5000);

            //Cancel the thread:
            //bg.CancelAsync();
 
            DoSomethingThatRequiresThreadCompleted();
            Console.ReadLine();
        }

        static void bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Console.WriteLine("Progress {0}", e.ProgressPercentage);
        }

        static void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
                ThreadCancelled = true;
            else
                theResult = (SomethingTheWorkerBuilds)e.Result;
        }

        static void bg_Work(object sender, DoWorkEventArgs e)
        {

                BackgroundWorker bg = sender as BackgroundWorker;
                for (int i = 0; i < 10; i++)
                {
                    if (bg.CancellationPending)
                    {
                        e.Cancel = true; break;
                    }
                    System.Threading.Thread.Sleep(1000);
                    bg.ReportProgress(i);
                }
                e.Result = new SomethingTheWorkerBuilds();
        }

        static void DoSomethingThatRequiresThreadCompleted()
        {
            Console.WriteLine("Waiting for thread");
            while (theResult==null  && !ThreadCancelled) { }
            if (ThreadCancelled)
                Console.WriteLine("Thread cancelled");
            else
                //Carry on
                Console.WriteLine(theResult.Text);
        }
    }

    class SomethingTheWorkerBuilds
    {
        public string Text = "Hello World";
    }
}
(ISTR I couldn't trust using BackgroundWorker.IsBusy because that would return false before 'theResult' was populated - but I might be wrong)
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform