using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace Misuzilla.Applications.TwitterIrcGateway { /// /// 遅延実行の処理を提供します。 /// public static class Deferred { /// /// 遅延実行の状態を表します。 /// /// public class DeferredState { public Boolean IsCanceled { get; private set; } public Boolean IsRunning { get; internal set; } public IAsyncResult AsyncResult { get; internal set; } public Func Target { get; internal set; } public ManualResetEvent WaitHandle { get; set; } /// /// 処理をキャンセルします。 /// /// キャンセル出来た場合にはtrue、既に実行が完了されたなどの理由でキャンセル出来なかった場合にはfalse public Boolean Cancel() { IsCanceled = true; if (AsyncResult.IsCompleted) { return false; } DeferredState state = AsyncResult.AsyncState as DeferredState; state.WaitHandle.Set(); Target.EndInvoke(AsyncResult); return IsRunning; } /// /// 遅延実行結果を取得します。処理が実行されていない場合には完了を待ちます。 /// /// public TResult Result() { return Target.EndInvoke(AsyncResult); } } /// /// /// /// /// /// /// /// private static DeferredState DeferredInvokeInternal(Func func, Int32 millisecond, AsyncCallback asyncCallback) { DeferredState state = new DeferredState(); state.WaitHandle = new ManualResetEvent(false); // 暫定で0から10秒 if (millisecond > 10 * 1000) millisecond = 10 * 1000; else if (millisecond < 0) millisecond = 0; Func d = () => { state.WaitHandle.WaitOne(millisecond); lock (state) { if (state.IsCanceled) { state.IsRunning = true; return default(TResult); } else { return func(); } } }; state.Target = d; state.AsyncResult = d.BeginInvoke(asyncCallback, state); return state; } /// /// メソッドを遅延実行します。 /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond) { return DeferredInvoke(func, millisecond, null); } /// /// コールバックを指定してメソッドを遅延実行します。 /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, AsyncCallback asyncCallback) { return DeferredInvokeInternal(func, millisecond, asyncCallback); } /// /// メソッドを遅延実行します。 /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, T arg1) { return DeferredInvoke(func, millisecond, null, arg1); } /// /// コールバックを指定してメソッドを遅延実行します。 /// /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, AsyncCallback asyncCallback, T arg1) { return DeferredInvokeInternal(() => func(arg1), millisecond, asyncCallback); } /// /// メソッドを遅延実行します。 /// /// /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, T1 arg1, T2 arg2) { return DeferredInvoke(func, millisecond, null, arg1, arg2); } /// /// コールバックを指定してメソッドを遅延実行します。 /// /// /// /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, AsyncCallback asyncCallback, T1 arg1, T2 arg2) { return DeferredInvokeInternal(() => func(arg1, arg2), millisecond, asyncCallback); } /// /// メソッドを遅延実行します。 /// /// /// /// /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, T1 arg1, T2 arg2, T3 arg3) { return DeferredInvoke(func, millisecond, null, arg1, arg2, arg3); } /// /// コールバックを指定してメソッドを遅延実行します。 /// /// /// /// /// /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, AsyncCallback asyncCallback, T1 arg1, T2 arg2, T3 arg3) { return DeferredInvokeInternal(() => func(arg1, arg2, arg3), millisecond, asyncCallback); } /// /// メソッドを遅延実行します。 /// /// /// /// /// /// /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { return DeferredInvoke(func, millisecond, null, arg1, arg2, arg3, arg4); } /// /// コールバックを指定してメソッドを遅延実行します。 /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static DeferredState DeferredInvoke(this Func func, Int32 millisecond, AsyncCallback asyncCallback, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { return DeferredInvokeInternal(() => func(arg1, arg2, arg3, arg4), millisecond, asyncCallback); } } }