BackgroundWorker utilities
Manual usage:
Register events and execute DoWork()
_bgHelper.AddDoWork(OnDowork).AddRunWorkerCompleted(OnCompleted)
.AddReportProgressChanged(OnReportProgress).SupportCancellation().DoWork();
BackgroundWorker events
private void OnDowork(object sender, DoWorkEventArgs e)
{
if (_bgHelper.CancellationPending)
{
e.Cancel = true;
return;
}
//TODO: Working progress
}
private void OnReportProgress(object sender, ProgressChangedEventArgs e)
{
//TODO: Report progress on working
}
private void OnCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//TODO: Working completed
}
using System;
using System.ComponentModel;
namespace App.Helpers
{
/// <summary>
/// Class BackgroundWorkerHelper.
/// Support execute action on background thread
/// </summary>
public class BackgroundWorkerHelper : IDisposable
{
#region Private variable
/// <summary>
/// The _added event do work
/// </summary>
private bool _addedEventDoWork;
/// <summary>
/// The _added event run worker completed
/// </summary>
private bool _addedEventRunWorkerCompleted;
/// <summary>
/// The _worker
/// </summary>
private BackgroundWorker _worker;
/// <summary>
/// The _on do work event handler
/// </summary>
private DoWorkEventHandler _onDoWorkEventHandler;
/// <summary>
/// The _on report progress changed
/// </summary>
private ProgressChangedEventHandler _onReportProgressChanged;
/// <summary>
/// The _on completed event handler
/// </summary>
private RunWorkerCompletedEventHandler _onCompletedEventHandler;
public bool CancellationPending
{
get
{
return _worker != null && _worker.CancellationPending;
}
}
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="BackgroundWorkerHelper"/> class.
/// </summary>
public BackgroundWorkerHelper() : this(new BackgroundWorker())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BackgroundWorkerHelper"/> class.
/// </summary>
/// <param name="worker">The worker.</param>
public BackgroundWorkerHelper(BackgroundWorker worker)
{
_worker = worker;
}
#endregion
#region Public functions
/// <summary>
/// Adds the DoWork event.
/// </summary>
/// <param name="onDoWorkEvent">The on do work event.</param>
/// <returns>BackgroundWorkerHelper.</returns>
public BackgroundWorkerHelper AddDoWork(DoWorkEventHandler onDoWorkEvent)
{
ReleaseEventHandler(); //Remove dupplicate event handler
_addedEventDoWork = true;
_onDoWorkEventHandler = onDoWorkEvent;
_worker.DoWork += OnDoWork;
return this;
}
/// <summary>
/// Adds the ReportProgressChanged event.
/// </summary>
/// <param name="onReportProgressChanged">The on report progress changed.</param>
/// <returns>BackgroundWorkerHelper.</returns>
public BackgroundWorkerHelper AddReportProgressChanged(ProgressChangedEventHandler onReportProgressChanged)
{
_worker.WorkerReportsProgress = true;
_onReportProgressChanged = onReportProgressChanged;
_worker.ProgressChanged += OnProgressChanged;
return this;
}
/// <summary>
/// Adds the RunWorkerCompleted event.
/// </summary>
/// <param name="onRunWorkerCompleted">The on run worker completed.</param>
/// <returns>BackgroundWorkerHelper.</returns>
public BackgroundWorkerHelper AddRunWorkerCompleted(RunWorkerCompletedEventHandler onRunWorkerCompleted)
{
_addedEventRunWorkerCompleted = true;
_onCompletedEventHandler = onRunWorkerCompleted;
return this;
}
/// <summary>
/// Supports the cancellation.
/// </summary>
/// <returns>BackgroundWorkerHelper.</returns>
public BackgroundWorkerHelper SupportCancellation()
{
_worker.WorkerSupportsCancellation = true;
return this;
}
/// <summary>
/// Does the work.
/// </summary>
/// <param name="obj">The object.</param>
public void DoWork(object obj = null)
{
if (_addedEventDoWork)
{
_worker.RunWorkerCompleted += OnRunWorkerCompleted;
_worker.RunWorkerAsync(obj);
}
}
/// <summary>
/// Cancels this instance.
/// </summary>
public void Cancel()
{
if (_worker.WorkerSupportsCancellation)
{
if (_worker.IsBusy)
{
_worker.CancelAsync();
}
//Release all event handler when cancel
ReleaseEventHandler();
}
}
/// <summary>
/// Determines whether this instance is busy.
/// </summary>
/// <returns><c>true</c> if this instance is busy; otherwise, <c>false</c>.</returns>
public bool IsBusy()
{
return _worker != null && _worker.IsBusy;
}
#endregion
#region Private functions
/// <summary>
/// Handles the <see cref="E:DoWork" /> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The <see cref="DoWorkEventArgs"/> instance containing the event data.</param>
private void OnDoWork(object sender, DoWorkEventArgs args)
{
_onDoWorkEventHandler(sender, args);
}
/// <summary>
/// Handles the <see cref="E:ProgressChanged" /> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The <see cref="ProgressChangedEventArgs"/> instance containing the event data.</param>
private void OnProgressChanged(object sender, ProgressChangedEventArgs args)
{
_onReportProgressChanged(sender, args);
}
/// <summary>
/// Handles the <see cref="E:RunWorkerCompleted" /> event.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The <see cref="RunWorkerCompletedEventArgs"/> instance containing the event data.</param>
private void OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args)
{
if (args.Error != null)
{
//TODO: Write Error Log
}
if (_onCompletedEventHandler != null)
{
_onCompletedEventHandler(sender, args);
}
//Release all registered event handler when completed
ReleaseEventHandler();
}
/// <summary>
/// Releases the event handler.
/// </summary>
private void ReleaseEventHandler()
{
if (_addedEventDoWork)
{
_worker.DoWork -= OnDoWork;
_onDoWorkEventHandler = null;
_addedEventDoWork = false;
}
if (_worker.WorkerReportsProgress)
{
_worker.ProgressChanged -= OnProgressChanged;
_onReportProgressChanged = null;
_worker.WorkerReportsProgress = false;
}
if (_addedEventRunWorkerCompleted)
{
_worker.RunWorkerCompleted -= OnRunWorkerCompleted;
_onCompletedEventHandler = null;
_addedEventRunWorkerCompleted = false;
}
}
#endregion
#region Disposable
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (_worker != null)
{
_worker.Dispose();
_worker = null;
}
}
}
~BackgroundWorkerHelper()
{
Dispose(false);
}
#endregion
}
}