Renamed ProgressUpdated event to ProgressChanged in order to conform with the status report naming convention; removed progress reporting from the Progression class; moved progress reporting into its own interface which is now optional to implement for any background task; renamed Progression to Waitable since it no longer has anything to do with progress; fixed unit tests
git-svn-id: file:///srv/devel/repo-conversion/nusu@64 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
1161ef8f25
commit
7dbfc3c422
15 changed files with 321 additions and 160 deletions
|
@ -43,7 +43,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// <summary>Called when the queue operations's progress changes</summary>
|
||||
/// <param name="sender">Queue operation whose progress has changed</param>
|
||||
/// <param name="e">Contains the new progress achieved</param>
|
||||
void ProgressUpdated(object sender, ProgressUpdateEventArgs e);
|
||||
void ProgressChanged(object sender, ProgressReportEventArgs e);
|
||||
|
||||
/// <summary>Called when the queue operation has ended</summary>
|
||||
/// <param name="sender">Queue operation that as ended</param>
|
||||
|
@ -61,7 +61,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
|
||||
/// <summary>Initializes a new ProgressUpdateEventArgsMatcher </summary>
|
||||
/// <param name="expected">Expected progress update event arguments</param>
|
||||
public ProgressUpdateEventArgsMatcher(ProgressUpdateEventArgs expected) {
|
||||
public ProgressUpdateEventArgsMatcher(ProgressReportEventArgs expected) {
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// True if the actual value matches the expected value; otherwise false
|
||||
/// </returns>
|
||||
public override bool Matches(object actualAsObject) {
|
||||
ProgressUpdateEventArgs actual = (actualAsObject as ProgressUpdateEventArgs);
|
||||
ProgressReportEventArgs actual = (actualAsObject as ProgressReportEventArgs);
|
||||
if(actual == null)
|
||||
return false;
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
}
|
||||
|
||||
/// <summary>Expected progress update event args value</summary>
|
||||
private ProgressUpdateEventArgs expected;
|
||||
private ProgressReportEventArgs expected;
|
||||
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,10 @@ namespace Nuclex.Support.Scheduling {
|
|||
#region class TestOperation
|
||||
|
||||
/// <summary>Progression used for testing in this unit test</summary>
|
||||
private class TestOperation : Operation {
|
||||
private class TestOperation : Operation, IProgressReporter {
|
||||
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressChanged;
|
||||
|
||||
/// <summary>Begins executing the operation. Yeah, sure :)</summary>
|
||||
public override void Start() { }
|
||||
|
@ -118,7 +121,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// New progress to be reported by the testing progression
|
||||
/// </param>
|
||||
public void ChangeProgress(float progress) {
|
||||
OnAsyncProgressUpdated(progress);
|
||||
OnAsyncProgressChanged(progress);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -130,6 +133,29 @@ namespace Nuclex.Support.Scheduling {
|
|||
throw this.exception;
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(float progress) {
|
||||
OnAsyncProgressChanged(new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(ProgressReportEventArgs eventArguments) {
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressChanged;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
/// <summary>Exception that has occured in the background process</summary>
|
||||
private volatile Exception exception;
|
||||
|
||||
|
@ -159,22 +185,22 @@ namespace Nuclex.Support.Scheduling {
|
|||
testQueueOperation.Start();
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
Method("ProgressChanged").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(QueueOperation<TestOperation>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.25f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.25f))
|
||||
}
|
||||
);
|
||||
|
||||
operation1.ChangeProgress(0.5f);
|
||||
|
||||
Expect.Once.On(mockedSubscriber).
|
||||
Method("ProgressUpdated").
|
||||
Method("ProgressChanged").
|
||||
With(
|
||||
new Matcher[] {
|
||||
new NMock2.Matchers.TypeMatcher(typeof(QueueOperation<TestOperation>)),
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressUpdateEventArgs(0.5f))
|
||||
new ProgressUpdateEventArgsMatcher(new ProgressReportEventArgs(0.5f))
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -191,8 +217,8 @@ namespace Nuclex.Support.Scheduling {
|
|||
this.mockery.NewMock<IQueueOperationSubscriber>();
|
||||
|
||||
operation.AsyncEnded += new EventHandler(mockedSubscriber.Ended);
|
||||
operation.AsyncProgressUpdated +=
|
||||
new EventHandler<ProgressUpdateEventArgs>(mockedSubscriber.ProgressUpdated);
|
||||
(operation as IProgressReporter).AsyncProgressChanged +=
|
||||
new EventHandler<ProgressReportEventArgs>(mockedSubscriber.ProgressChanged);
|
||||
|
||||
return mockedSubscriber;
|
||||
}
|
||||
|
|
|
@ -32,15 +32,8 @@ namespace Nuclex.Support.Scheduling {
|
|||
public class QueueOperation<OperationType> : Operation
|
||||
where OperationType : Operation {
|
||||
|
||||
/// <summary>Initializes a new queue operation</summary>
|
||||
private QueueOperation() {
|
||||
this.asyncOperationEndedDelegate = new EventHandler(asyncOperationEnded);
|
||||
this.asyncOperationProgressUpdatedDelegate = new EventHandler<ProgressUpdateEventArgs>(
|
||||
asyncOperationProgressUpdated
|
||||
);
|
||||
|
||||
this.children = new List<WeightedProgression<OperationType>>();
|
||||
}
|
||||
/// <summary>will be triggered to report when progress has been achieved</summary>
|
||||
public event EventHandler<ProgressReportEventArgs> AsyncProgressUpdated;
|
||||
|
||||
/// <summary>Initializes a new queue operation with default weights</summary>
|
||||
/// <param name="childs">Child operations to execute in this operation</param>
|
||||
|
@ -74,6 +67,16 @@ namespace Nuclex.Support.Scheduling {
|
|||
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new queue operation</summary>
|
||||
private QueueOperation() {
|
||||
this.asyncOperationEndedDelegate = new EventHandler(asyncOperationEnded);
|
||||
this.asyncOperationProgressChangedDelegate = new EventHandler<ProgressReportEventArgs>(
|
||||
asyncOperationProgressChanged
|
||||
);
|
||||
|
||||
this.children = new List<WeightedProgression<OperationType>>();
|
||||
}
|
||||
|
||||
/// <summary>Provides access to the child operations of this queue</summary>
|
||||
public IList<WeightedProgression<OperationType>> Children {
|
||||
get { return this.children; }
|
||||
|
@ -93,6 +96,29 @@ namespace Nuclex.Support.Scheduling {
|
|||
throw this.exception;
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="progress">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(float progress) {
|
||||
OnAsyncProgressChanged(new ProgressReportEventArgs(progress));
|
||||
}
|
||||
|
||||
/// <summary>Fires the progress update event</summary>
|
||||
/// <param name="eventArguments">Progress to report (ranging from 0.0 to 1.0)</param>
|
||||
/// <remarks>
|
||||
/// Informs the observers of this progression about the achieved progress.
|
||||
/// Allows for classes derived from the Progression class to easily provide
|
||||
/// a custom event arguments class that has been derived from the
|
||||
/// Progression's ProgressUpdateEventArgs class.
|
||||
/// </remarks>
|
||||
protected virtual void OnAsyncProgressChanged(ProgressReportEventArgs eventArguments) {
|
||||
EventHandler<ProgressReportEventArgs> copy = AsyncProgressUpdated;
|
||||
if(copy != null)
|
||||
copy(this, eventArguments);
|
||||
}
|
||||
|
||||
/// <summary>Prepares the current operation and calls its Begin() method</summary>
|
||||
/// <remarks>
|
||||
/// This subscribes the queue to the events of to the current operation
|
||||
|
@ -102,7 +128,10 @@ namespace Nuclex.Support.Scheduling {
|
|||
OperationType operation = this.children[this.currentOperationIndex].Progression;
|
||||
|
||||
operation.AsyncEnded += this.asyncOperationEndedDelegate;
|
||||
operation.AsyncProgressUpdated += this.asyncOperationProgressUpdatedDelegate;
|
||||
|
||||
IProgressReporter progressReporter = operation as IProgressReporter;
|
||||
if(progressReporter != null)
|
||||
progressReporter.AsyncProgressChanged += this.asyncOperationProgressChangedDelegate;
|
||||
|
||||
operation.Start();
|
||||
}
|
||||
|
@ -118,7 +147,10 @@ namespace Nuclex.Support.Scheduling {
|
|||
|
||||
// Disconnect from the operation's events
|
||||
operation.AsyncEnded -= this.asyncOperationEndedDelegate;
|
||||
operation.AsyncProgressUpdated -= this.asyncOperationProgressUpdatedDelegate;
|
||||
|
||||
IProgressReporter progressReporter = operation as IProgressReporter;
|
||||
if(progressReporter != null)
|
||||
progressReporter.AsyncProgressChanged -= this.asyncOperationProgressChangedDelegate;
|
||||
|
||||
try {
|
||||
operation.Join();
|
||||
|
@ -127,7 +159,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
this.completedWeight += this.children[this.currentOperationIndex].Weight;
|
||||
|
||||
// Trigger another progress update
|
||||
OnAsyncProgressUpdated(this.completedWeight / this.totalWeight);
|
||||
OnAsyncProgressChanged(this.completedWeight / this.totalWeight);
|
||||
}
|
||||
catch(Exception exception) {
|
||||
this.exception = exception;
|
||||
|
@ -165,7 +197,7 @@ namespace Nuclex.Support.Scheduling {
|
|||
/// <summary>Called when currently executing operation makes progress</summary>
|
||||
/// <param name="sender">Operation that has achieved progress</param>
|
||||
/// <param name="e">Not used</param>
|
||||
private void asyncOperationProgressUpdated(object sender, ProgressUpdateEventArgs e) {
|
||||
private void asyncOperationProgressChanged(object sender, ProgressReportEventArgs e) {
|
||||
|
||||
// Determine the completed weight of the currently executing operation
|
||||
float currentOperationCompletedWeight =
|
||||
|
@ -176,14 +208,14 @@ namespace Nuclex.Support.Scheduling {
|
|||
(this.completedWeight + currentOperationCompletedWeight) / this.totalWeight;
|
||||
|
||||
// Done, we can send the actual progress to any event subscribers
|
||||
OnAsyncProgressUpdated(progress);
|
||||
OnAsyncProgressChanged(progress);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Delegate to the asyncOperationEnded() method</summary>
|
||||
private EventHandler asyncOperationEndedDelegate;
|
||||
/// <summary>Delegate to the asyncOperationProgressUpdated() method</summary>
|
||||
private EventHandler<ProgressUpdateEventArgs> asyncOperationProgressUpdatedDelegate;
|
||||
private EventHandler<ProgressReportEventArgs> asyncOperationProgressChangedDelegate;
|
||||
/// <summary>Operations being managed in the queue</summary>
|
||||
private List<WeightedProgression<OperationType>> children;
|
||||
/// <summary>Summed weight of all operations in the queue</summary>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue