Fixed documentation of Waitable and Request classes; wrote down some ideas to improve the request framework

git-svn-id: file:///srv/devel/repo-conversion/nusu@75 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2008-06-05 19:19:00 +00:00
parent 73ef5de576
commit e0cf91a0a4
4 changed files with 88 additions and 21 deletions

View File

@ -0,0 +1,68 @@
The request framework should not require that .NET multithreading is used for
asynchronous requests.
Otherwise, it would prvent overlapped operations, 3rd party APIs (eg. used
via P/Invoke) from being able to use the request framework and possibly even
spawn duplicate implementations.
Design using interfaces:
interface IWaitable {
/// <summary>Fired when the background process has finished</summary>
/// <remarks>
/// If the process is already finished when a client registers to this event,
/// the registered callback will be invoked synchronously right when the
/// registration takes place.
/// </remarks>
event EventHandler Finished;
/// <summary>Waits until the background process finishes</summary>
void Wait();
/// <summary>Waits until the background process finishes or a timeout occurs</summary>
/// <param name="timeoutMilliseconds">
/// Number of milliseconds after which to stop waiting and return immediately
/// </param>
/// <returns>
/// True if the background process completed, false if the timeout was reached
/// </returns>
bool Wait(int timeoutMilliseconds);
/// <summary>Whether the background process has finished</summary>
bool Finished { get; }
}
interface IThreadedWaitable : IWaitable {
WaitHandle WaitHandle { get; }
}
interface IRequest : IWaitable {
/// <summary>
/// Waits for the background process to complete and re-throws the exception to
/// the caller when an error has occured
/// </summary>
void Join();
}
interface IRequest<ResultType> : IRequest {
/// <summary>
/// Waits for the background process to complete and re-throws the exception to
/// the caller when an error has occured
/// </summary>
/// <returns>The result of the background processing</returns>
new ResultType Join();
}
interface IThreadedRequest : IRequest, IThreadedWaitable { }
interface IThreadedRequest<ResultType> :
IRequest<ResultType>, IThreadedRequest, IThreadedWaitable { }

View File

@ -217,6 +217,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Documents\Nuclex.Support.txt" /> <Content Include="Documents\Nuclex.Support.txt" />
<Content Include="Documents\Request Framework.txt" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\v3.0\Microsoft.Xna.GameStudio.Common.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\v3.0\Microsoft.Xna.GameStudio.Common.targets" />

View File

@ -70,7 +70,7 @@ namespace Nuclex.Support.Tracking {
/// <returns> /// <returns>
/// A failed request that reports the provided exception as cause for its failure /// A failed request that reports the provided exception as cause for its failure
/// </returns> /// </returns>
public static Request CreateFailedDummyRequest(Exception exception) { public static Request CreateFailedDummy(Exception exception) {
return new EndedDummyRequest(exception); return new EndedDummyRequest(exception);
} }
@ -134,7 +134,7 @@ namespace Nuclex.Support.Tracking {
/// <returns> /// <returns>
/// A failed request that reports the provided exception as cause for its failure /// A failed request that reports the provided exception as cause for its failure
/// </returns> /// </returns>
public static new Request CreateFailedDummyRequest(Exception exception) { public static new Request CreateFailedDummy(Exception exception) {
return new EndedDummyRequest(exception); return new EndedDummyRequest(exception);
} }

View File

@ -23,9 +23,7 @@ using System.Threading;
namespace Nuclex.Support.Tracking { namespace Nuclex.Support.Tracking {
/// <summary> /// <summary>Base class for background processes the user can wait on</summary>
/// Base class for actions on which that give an indication of their progress
/// </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// By encapsulating long-running operations which will ideally be running in /// By encapsulating long-running operations which will ideally be running in
@ -40,27 +38,27 @@ namespace Nuclex.Support.Tracking {
/// task has completed. This class deliberately does not provide an Execute() /// task has completed. This class deliberately does not provide an Execute()
/// method or anything similar to clearly seperate the initiation of an operation /// method or anything similar to clearly seperate the initiation of an operation
/// from just monitoring it. By omitting an Execute() method, it also becomes /// from just monitoring it. By omitting an Execute() method, it also becomes
/// possible to construct a progression just-in-time when it is explicitely being /// possible to construct a Waitable just-in-time when it is explicitely being
/// asked for. /// asked for.
/// </para> /// </para>
/// </remarks> /// </remarks>
public abstract class Waitable { public abstract class Waitable {
#region class EndedDummyProgression #region class EndedDummyWaitable
/// <summary>Dummy progression which always is in the 'ended' state</summary> /// <summary>Dummy waitable which always is in the 'ended' state</summary>
private class EndedDummyWaitable : Waitable { private class EndedDummyWaitable : Waitable {
/// <summary>Initializes a new ended dummy progression</summary> /// <summary>Initializes a new ended dummy waitable</summary>
public EndedDummyWaitable() { public EndedDummyWaitable() {
OnAsyncEnded(); OnAsyncEnded();
} }
} }
#endregion // class EndedDummyProgression #endregion // class EndedDummyWaitable
/// <summary>A dummy progression that's always in the 'ended' state</summary> /// <summary>A dummy waitable that's always in the 'ended' state</summary>
/// <remarks> /// <remarks>
/// Useful if an operation is already complete when it's being asked for or /// Useful if an operation is already complete when it's being asked for or
/// when a progression that's lazily created is accessed after the original /// when a progression that's lazily created is accessed after the original
@ -68,15 +66,15 @@ namespace Nuclex.Support.Tracking {
/// </remarks> /// </remarks>
public static readonly Waitable EndedDummy = new EndedDummyWaitable(); public static readonly Waitable EndedDummy = new EndedDummyWaitable();
/// <summary>Will be triggered when the progression has ended</summary> /// <summary>Will be triggered when the Waitable has ended</summary>
public event EventHandler AsyncEnded; public event EventHandler AsyncEnded;
/// <summary>Whether the progression has ended already</summary> /// <summary>Whether the Waitable has ended already</summary>
public bool Ended { public bool Ended {
get { return this.ended; } get { return this.ended; }
} }
/// <summary>WaitHandle that can be used to wait for the progression to end</summary> /// <summary>WaitHandle that can be used to wait for the Waitable to end</summary>
public WaitHandle WaitHandle { public WaitHandle WaitHandle {
get { get {