Monday, February 10, 2014

.Net Winforms Basic BackgroundWorker Example

I use a BackgroundWorker a lot when working with WinForms in order to perform database or webservice calls without freezing the UI thread. Of course web services can be called using their built in asynchronously methods however when you have a separate data access or model layer, these asynchronous methods are not readily available. 

On a new project I was working on, I was looking for a basic example online for quick reference but there wasn't one amongst the top search results so I thought I'd post one.

    using System.ComponentModel;
    using System.Threading;
    using System.Windows.Forms;

    public partial class MainForm : Form
    {
        private readonly BackgroundWorker backgroundWorker = new BackgroundWorker();

        public MainForm()
        {
            this.InitializeComponent();
            this.backgroundWorker.DoWork += this.BackgroundWorkerDoWork;
            this.backgroundWorker.RunWorkerCompleted += this.BackgroundWorkerCompleted;
            this.backgroundWorker.RunWorkerAsync("Passed Argument");
        }

        private void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            Thread.Sleep(1000);
            e.Result = e.Argument;
        }

        private void BackgroundWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show(e.Result.ToString());
            //// Shows "Passed Argument"
        }
    }

Keep in mind you can not run a background worker that is always running so you probably want to do an:
if (this.backgroundWorker.IsBusy)
{
    //// Perhaps do something like put the RunWork request in a Queue.
    //// Once RunWorkerCompleted is fired, Dequeue an kick off the background
    //// worker again.
}
else
{
    this.backgroundWorker.RunWorkerAsync("Passed Argument");
}
For example:
        private readonly Queue<string> queue = new Queue<string>();

        private void InitializeRunWorkerCompleted()
        {
            this.backgroundWorker.RunWorkerCompleted += (sender, e) =>
            {
                if (this.queue.Count > 0)
                {
                    this.backgroundWorker.RunWorkerAsync(this.queue.Dequeue());
                }
                
                //// Regular logic here.
            };
        }

No comments:

Post a Comment