Permalink
Browse files

Add fluent deferred-delegate-execution implementation

  • Loading branch information...
1 parent 2b392ff commit 2a16e81af8731ee221dca9cdc078159c0dc309d2 @cdhowie committed Oct 8, 2012
@@ -61,6 +61,8 @@
<Compile Include="Xml.Linq\Common.cs" />
<Compile Include="Xml.Linq\XAttributeExtensions.cs" />
<Compile Include="Xml.Linq\XElementExtensions.cs" />
+ <Compile Include="Delegates\Extensions.cs" />
+ <Compile Include="Delegates\Defer.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -70,4 +72,7 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+ <ItemGroup>
+ <Folder Include="Delegates\" />
+ </ItemGroup>
+</Project>
@@ -0,0 +1,119 @@
+//
+// Defer.cs
+//
+// Author:
+// Chris Howie <me@chrishowie.com>
+//
+// Copyright (c) 2012 Chris Howie
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace Cdh.Toolkit.Extensions.Delegates
+{
+ public static class Defer
+ {
+ public static DeferState Action(Action action)
+ {
+ if (action == null) throw new ArgumentNullException("action");
+
+ return new DeferState(action);
+ }
+
+ public class DeferState
+ {
+ private Action action;
+ private List<Func<Exception, bool>> exceptionHandlers = new List<Func<Exception, bool>>();
+
+ internal DeferState(Action action)
+ {
+ this.action = action;
+ }
+
+ public void For(TimeSpan timeSpan)
+ {
+ if (timeSpan.CompareTo(TimeSpan.Zero) <= 0) {
+ throw new ArgumentOutOfRangeException("timeSpan", timeSpan, "Must be greater than TimeSpan.Zero.");
+ }
+
+ Action processor = delegate {
+ Thread.Sleep(timeSpan);
+
+ try {
+ action();
+ } catch (Exception ex) {
+ var handled = false;
+
+ foreach (var handler in exceptionHandlers) {
+ handled = handler(ex);
+ if (handled) {
+ break;
+ }
+ }
+
+ if (!handled) {
+ throw;
+ }
+ }
+ };
+
+ AsyncCallback callback = result => processor.EndInvoke(result);
+
+ processor.BeginInvoke(callback, null);
+ }
+
+ public void Until(DateTime dateTime)
+ {
+ var span = dateTime.ToUniversalTime() - DateTime.UtcNow;
+
+ if (span.CompareTo(TimeSpan.Zero) <= 0) {
+ throw new ArgumentOutOfRangeException("dateTime", dateTime, "Must represent a point of time in the future.");
+ }
+
+ For(span);
+ }
+
+ public DeferState Handling<T>(Action<T> exceptionHandler)
+ where T : Exception
+ {
+ exceptionHandlers.Add(ex => {
+ if (ex is T) {
+ exceptionHandler((T)ex);
+ return true;
+ }
+
+ return false;
+ });
+
+ return this;
+ }
+
+ public DeferState HandlingAll()
+ {
+ exceptionHandlers.Add(ex => true);
+
+ return this;
+ }
+ }
+ }
+}
+
@@ -0,0 +1,38 @@
+//
+// Extensions.cs
+//
+// Author:
+// Chris Howie <me@chrishowie.com>
+//
+// Copyright (c) 2012 Chris Howie
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+
+namespace Cdh.Toolkit.Extensions.Delegates
+{
+ public static class Extensions
+ {
+ public static Defer.DeferState Defer(this Action action)
+ {
+ return Cdh.Toolkit.Extensions.Delegates.Defer.Action(action);
+ }
+ }
+}
+

0 comments on commit 2a16e81

Please sign in to comment.