Monday, June 14, 2010

Unhandled exception in BackgroundWorker

I was using the BackgroundWorker in WPF and had an unhandled exception
there and needed a better way to deal with this error. This is how I
did it:
I used the RunWorkerCompleted event. In this event, if the e.Error !=
null, I set a string value ErrorMessage to the message, and I call a
function ErrorOccurred which then raises an event that my calling
application caught. Below is my code:

My main Class

This code is just put together and probably won't work, but should
give you the general idea. This is my Window that calls the
background worker. I have two events, Finished and Error. If the
Error occurs, I do something, if its finishes successfully I do
something else.
public partial class MainWindow : Window
{
private DoWork Worker = new DoWork();

public MainWindow()
{
InitializeComponent();
Worker.Finished += new FinishedEventHandler(Worker_Finished);
Worker.Error += new ErrorEventHandler(Worker_Error);
}

void Worker_Finished(object sender, EventArgs e, List<Response> rList)
{
//do something when finished
}
void Worker_Error(object sender, EventArgs e, string errorMessage)
{
//do something if error
}

private void btnWork_ItemClick(object sender, ClickEventArgs e)
{
if (!Worker.IsBusy())
{
Worker.DoWork();
}
}
}

This is my Worker class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;

namespace MyNamespace
{
// A delegate type for hooking up when the backgroundworker is
finished. It returns the Response object
public delegate void FinishedEventHandler(object sender, EventArgs
e, List<Something> rList);
public delegate void ErrorEventHandler(object sender, EventArgs e,
string errorMessage);

public class DoWork
{

public BackgroundWorker worker;
List<Response> ResponseList;// = new List<Response>();
string ErrorMessage;


// An event that clients can use to be notified whenever the
// elements Backgroundworker is finished
public event FinishedEventHandler Finished;
public event ErrorEventHandler Error;

protected virtual void WorkCompleted(EventArgs e)
{
if (Finished != null)
Finished(this, e, ResponseList);
}

protected virtual void ErrorOccurred(EventArgs e)
{
if (Error != null)
Error(this, e, ErrorMessage);
}

/// <summary>
/// Main calls are
/// IsBusy, DoWork and CancelWork. It has a event called
FinishedEventHandler
/// that is raised when the work is completed
/// </summary>
public CheckResponse()
{
// Create a Background Worker
worker = new BackgroundWorker();

// Enable support for cancellation
worker.WorkerSupportsCancellation = true;
worker.DoWork +=
new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}

/// <summary>
/// when the work is completed return anobject and set r to its value
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void worker_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
ErrorMessage = "An error occurred. " + e.Error.Message;
ErrorOccurred(EventArgs.Empty);
}
else
{
ResponseList = (List<Response>)e.Result;
WorkCompleted(EventArgs.Empty);
}
}
/// <summary>
/// </summary>
/// <param name="sender"><param>
/// <param name="e"></param>
private void worker_DoWork(
object sender, DoWorkEventArgs e)
{
try
{
e.Result = Some call that returns a List
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

/// <summary>
/// Returns the status of the Backgroundworker. if its busy or not
/// </summary>
/// <returns></returns>
public bool IsBusy()
{
return worker.IsBusy;
}
/// <summary>
/// Can be called to cancel a backgroundworker
/// </summary>
public void CancelWork()
{
worker.CancelAsync();
}
/// <summary>
/// If the backgroundworker is not busy it starts the worker.
/// </summary>
public void DoWork()
{
if (!worker.IsBusy)
{
worker.RunWorkerAsync();
}
}
}
}

No comments: