|
using System;
using System.Collections.Generic;
namespace TaskManagerDemo.Utility
{
/// <summary>
/// Subterfuge required to get around the compiler being just a teeny bit too strict.
/// </summary>
/// <param name="sender">An event handler's sender argument.</param>
/// <param name="e">An event handler's EventArgs (or derived-class) argument.</param>
public delegate void GenericEventHandler(object sender, object e);
/// <summary>
/// Facilitates queueing of the processing of results from a sequence of asynchronous service method calls.
/// </summary>
public class QueuedAsyncServiceCallManager : AsyncServiceCallManager
{
/// <summary>
/// Gets / sets an indicator that the async service call has returned its result
/// (the associated ...AsyncCompleted event handler has been called).
/// </summary>
public bool ResultReturned { get; set; }
/// <summary>
/// Represents a task that must be in Completed Status before processing of the returned result can begin;
/// Basically places this task and the Prerequisite task in a queue.
/// </summary>
public TaskManager Prerequisite { get; set; }
// Event handler(s) to be called when the Prerequisite task reaches Completed Status.
private List<EventProcessor> _eventProcessorList = new List<EventProcessor>();
// C'tor.
public QueuedAsyncServiceCallManager(string name) : base(name) { }
/// <summary>
/// Adds the specified event handler and its arguments to the list of handlers associated with this task that will be
/// called when the Prerequisite task reaches Completed status, OR
/// Calls the event handler with its arguments immediately if the Prerequisite task is null or already in Completed
/// Status.
/// </summary>
/// <param name="handler">An event handler, usually an ...AsyncCompleted event handler.</param>
/// <param name="e">The EventArgs or derived-class object associated with / required by the specified event handler.
/// </param>
public void EnqueueResultHandling(GenericEventHandler handler, object sender, EventArgs e)
{
EventProcessor ep = new EventProcessor { Handler = handler, Sender = sender, Args = e };
if (Prerequisite == null || Prerequisite.Status == TaskStatus.Completed)
{
ep.Handler(ep.Sender, ep.Args);
}
else
{
if (!_eventProcessorList.Contains(ep))
{
_eventProcessorList.Add(ep);
Prerequisite.StatusChanged += new EventHandler<EventArgs>(Prerequisite_StatusChanged);
}
}
}
// Handler for the Prequisite task's StatusChanged event.
private void Prerequisite_StatusChanged(object sender, EventArgs e)
{
if (Prerequisite == null || Prerequisite.Status == TaskStatus.Completed)
{
foreach (EventProcessor ep in _eventProcessorList)
{
ep.Handler(ep.Sender, ep.Args);
}
_eventProcessorList.Clear();
}
else
{
ResultReturned = false;
}
}
// Encapsulates an event handler with its arguments and enables determination of equality and thus
// identification of duplicates.
private class EventProcessor : IEquatable<EventProcessor>
{
public GenericEventHandler Handler { get; set; }
public object Sender { get; set; }
public object Args { get; set; }
#region IEquatable<EventProcessor> Members
public bool Equals(EventProcessor other)
{
return (Handler.Equals(other.Handler) && Sender.Equals(other.Sender) && Args.Equals(other.Args));
}
#endregion IEquatable<EventProcessor> Members
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
George Henry has worked as a software developer for more than 20 years. He is currently employed by Concur in Bellevue, Washington, USA.