MachineEngine(AsyncMachine machine, P param);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10);
+ public delegate IEnumerable MachineEngine(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10, P11 param11);
+
+ // General purpose async machine which supports single (optimized) and multiple
+ // asynchronous operations
+ public class AsyncMachine : IAsyncResult, IDisposable
+ {
+ #region Helper static methods
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine
engine, P param, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8, param9));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngine engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10, P11 param11, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11));
+ return machine;
+ }
+
+
+ public static void EndAsyncMachine(IAsyncResult result)
+ {
+ using (AsyncMachine machine = (AsyncMachine)result)
+ {
+ machine.End();
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ public AsyncMachine(AsyncCallback callback, object state)
+ {
+ this.asyncMachineCompletionCallback = callback;
+ this.AsyncState = state;
+
+ this.CompletionCallback = this.SingleOperationCompletionCallback;
+ this.moveNextLock = new object();
+ }
+
+ #endregion
+
+
+ // Create completion port with infinite timeout
+ public CompletionPort CreateCompletionPort(int totalOperationsCount)
+ {
+ return CreateCompletionPort(totalOperationsCount, CompletionPort.InfiniteWait);
+ }
+
+ // Create completion port with specified timeout
+ public CompletionPort CreateCompletionPort(int totalOperationsCount, TimeSpan timeout)
+ {
+ return CreateCompletionPort(totalOperationsCount, totalOperationsCount, timeout);
+ }
+
+ // Creates completion port in the quorum mode with a specified timeout (you can use CompletionPort.InfiniteWait
+ // for infinite timeout)
+ public CompletionPort CreateCompletionPort(int totalOperationsCount, int quorumOperationsCount)
+ {
+ return CreateCompletionPort(
+ totalOperationsCount,
+ quorumOperationsCount,
+ CompletionPort.InfiniteWait);
+ }
+
+ // Creates completion port in the quorum mode with a specified timeout (you can use CompletionPort.InfiniteWait
+ // for infinite timeout)
+ public CompletionPort CreateCompletionPort(int totalOperationsCount, int quorumOperationsCount, TimeSpan timeout)
+ {
+ if (this.Enumerator == null)
+ {
+ throw new InvalidOperationException("Async machine either hasn't started yet or has already completed.");
+ }
+
+ return new CompletionPort(
+ this.AsyncMachineResumeCallback,
+ totalOperationsCount,
+ quorumOperationsCount,
+ timeout);
+ }
+
+ public delegate void ExceptionCleanupDelegate(object sender, EventArgs e);
+
+ // Event which is fired when exception cleanup is required
+ public event ExceptionCleanupDelegate ExceptionCleanup;
+
+ // Starts executing of the async machine
+ public void Start(IEnumerable machine)
+ {
+ Debug.Assert(null == this.Enumerator || this.IsCompleted);
+
+ if (null == machine)
+ {
+ throw new ArgumentNullException("machine");
+ }
+
+ this.Enumerator = machine.GetEnumerator();
+ this.IsCompleted = false;
+ this.Error = null;
+
+ if (this.waitHandle != null)
+ {
+ this.waitHandle.Reset();
+ }
+
+ lock (this.moveNextLock)
+ {
+ this.CompletedSynchronously = true;
+
+ this.MoveNext();
+
+ if (!this.IsCompleted)
+ {
+ this.CompletedSynchronously = false;
+ }
+ }
+ }
+
+ // Ends the async machine and waits for its completion if necessary
+ public void End()
+ {
+ if (!this.IsCompleted)
+ {
+ this.AsyncWaitHandle.WaitOne();
+ }
+
+ Debug.Assert(this.IsCompleted);
+
+ if (this.Error != null)
+ {
+ throw this.Error.PrepareServerStackForRethrow();
+ }
+ }
+
+ // A callback supplied to a single asynchronous operation to get notified when it's completed
+ public AsyncCallback CompletionCallback { get; private set; }
+
+ // A result of completed single asynchronous operation when AsyncMachine.CompletionCallback is used
+ public IAsyncResult CompletionResult
+ {
+ get
+ {
+ if (this.completionResult == null)
+ {
+ throw new InvalidOperationException("Completion result is not available yet.");
+ }
+
+ return this.completionResult;
+ }
+ }
+
+ #region IAsyncResult Members
+
+ public object AsyncState { get; private set; }
+
+ public WaitHandle AsyncWaitHandle
+ {
+ get
+ {
+ if (null == this.waitHandle)
+ {
+ lock (this.moveNextLock)
+ {
+ if (null == this.waitHandle)
+ {
+ this.waitHandle = new EventWaitHandle(this.IsCompleted, EventResetMode.ManualReset);
+ }
+ }
+ }
+
+ return this.waitHandle;
+ }
+ }
+
+ public bool CompletedSynchronously { get; private set; }
+
+ public bool IsCompleted { get; private set; }
+
+ #endregion
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool isDisposing)
+ {
+ if(isDisposing)
+ {
+ if (this.waitHandle != null)
+ {
+ // TODO: CLU
+ this.waitHandle.Dispose();
+ //this.waitHandle.Close();
+ this.waitHandle = null;
+ }
+
+ if (this.WakeUpTimer != null)
+ {
+ this.WakeUpTimer.Dispose();
+ this.WakeUpTimer = null;
+ }
+ }
+ }
+
+ #endregion
+
+ #region Private Members
+
+ private void MoveNext()
+ {
+ lock (this.moveNextLock)
+ {
+ using (this.EnterThreadContext())
+ {
+ this.MoveNextInternal();
+ }
+ }
+ }
+
+ private void MoveNextInternal()
+ {
+ Debug.Assert(this.Enumerator != null);
+ Debug.Assert(!this.IsCompleted);
+ Debug.Assert(null == this.Error);
+
+ if (!this.InsideMoveNext)
+ {
+ try
+ {
+ try
+ {
+ this.InsideMoveNext = true;
+ this.IsCompleted = !this.Enumerator.MoveNext();
+
+ if (!this.IsCompleted)
+ {
+ if (this.Enumerator.Current == null)
+ {
+ throw new InvalidOperationException("Completion port for current iteration is null.");
+ }
+
+ if (!this.Enumerator.Current.IsSingleOperation)
+ {
+ if (this.Enumerator.Current.TotalOperationsCount == 0)
+ {
+ // No operations are specified on the port, do another machine iteration
+ this.InsideMoveNext = false;
+ this.MoveNext();
+ return;
+ }
+ else
+ {
+ // Check if we should schedule a wake up for the current completion port. That needs to happen
+ // when we use non-optimized completion port with a timeout
+ if (!this.Enumerator.Current.Timeout.Equals(CompletionPort.InfiniteWait))
+ {
+ if (this.WakeUpTimer != null)
+ {
+ this.WakeUpTimer.Dispose();
+ }
+
+ //
+ // BUGBUG: Too expensive. Use single active task to implement timers
+ //
+ this.WakeUpTimer = new Timer(
+ this.CompletionPortTimeoutCallback,
+ this.Enumerator.Current,
+ this.Enumerator.Current.Timeout,
+ CompletionPort.InfiniteWait);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ this.InsideMoveNext = false;
+ }
+ }
+ catch (Exception e)
+ {
+ if (e.IsCritical())
+ {
+ Trace.TraceError("Failed to forward message: {0}", e);
+ throw;
+ }
+
+ Trace.TraceWarning("Failed to forward message: {0}", e);
+
+ this.Error = e;
+ this.IsCompleted = true;
+
+ if (this.ExceptionCleanup != null)
+ {
+ this.ExceptionCleanup(this, EventArgs.Empty);
+ }
+ }
+
+ this.CompletedMoveNext();
+
+ if (this.AsyncMethodCompletedSynchronously && !this.IsCompleted)
+ {
+ this.AsyncMethodCompletedSynchronously = false;
+
+ this.MoveNext();
+ }
+ }
+ else
+ {
+ //
+ // Call to asynchronous I/O was completed synchronously (i.e. this thread is currently executing MoveNext down the stack)
+ //
+
+ Debug.Assert(!this.AsyncMethodCompletedSynchronously);
+
+ this.AsyncMethodCompletedSynchronously = true;
+ }
+ }
+
+ private void CompletedMoveNext()
+ {
+ if (this.IsCompleted)
+ {
+ this.Enumerator = null;
+
+ if (null != this.waitHandle)
+ {
+ this.waitHandle.Set();
+ }
+
+ if (this.asyncMachineCompletionCallback != null)
+ {
+ this.asyncMachineCompletionCallback((IAsyncResult)this);
+ }
+ }
+ }
+
+ // Called by the WakeUpTimer when a scheduled timeout wait for the given completion
+ // port is expired
+ private void CompletionPortTimeoutCallback(object state)
+ {
+ Debug.Assert(state != null);
+
+ CompletionPort port = (CompletionPort)state;
+
+ port.TimeOutPort();
+ }
+
+ // Called by the completion port when quorum of asynchronous operations are completed
+ private void AsyncMachineResumeCallback()
+ {
+ // Check if quorum was reached with all operations finishing synchronously
+ if (!this.InsideMoveNext)
+ {
+ IEnumerator enumerator = this.Enumerator;
+
+ // It should never happen that this callback is called for CompletionPort with single operation
+ if (enumerator != null && enumerator.Current != null && enumerator.Current.IsSingleOperation)
+ {
+ throw new InvalidOperationException("CompletionPort.SingleOperation was used.");
+ }
+ }
+
+ this.MoveNext();
+ }
+
+ // Called by the completed single asynchronous operation
+ private void SingleOperationCompletionCallback(IAsyncResult asyncResult)
+ {
+ if (asyncResult == null)
+ {
+ throw new ArgumentNullException("asyncResult");
+ }
+
+ Debug.Assert(this.InsideMoveNext || this.Enumerator != null);
+ Debug.Assert(this.InsideMoveNext || this.Enumerator.Current != null);
+
+ this.completionResult = asyncResult;
+
+ this.MoveNext();
+ }
+
+ #region Thread Context helpers
+
+ private IDisposable EnterThreadContext()
+ {
+ return null;
+ }
+ #endregion
+
+ private IEnumerator Enumerator { get; set; }
+ private Exception Error { get; set; }
+ private bool InsideMoveNext { get; set; }
+ private bool AsyncMethodCompletedSynchronously { get; set; }
+ private Timer WakeUpTimer { get; set; }
+ private EventWaitHandle waitHandle;
+ private IAsyncResult completionResult;
+ private readonly AsyncCallback asyncMachineCompletionCallback;
+ private readonly object moveNextLock;
+ #endregion
+ }
+
+ #region Parameterized async machines
+
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P param);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10);
+ public delegate IEnumerable MachineEngineT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10, P11 param11);
+
+ public sealed class AsyncMachine : AsyncMachine
+ {
+ #region Helper static methods
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P param, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8, param9));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10));
+ return machine;
+ }
+
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "EndAsyncMachine does the disposing")]
+ public static IAsyncResult BeginAsyncMachine(MachineEngineT engine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10, P11 param11, AsyncCallback callback, object asyncState)
+ {
+ AsyncMachine machine = new AsyncMachine(callback, asyncState);
+ machine.Start(engine(machine, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11));
+ return machine;
+ }
+
+ public new static T EndAsyncMachine(IAsyncResult result)
+ {
+ using (AsyncMachine machine = (AsyncMachine)result)
+ {
+ machine.End();
+ return machine.ParameterValue;
+ }
+ }
+
+ #endregion
+
+ public AsyncMachine()
+ : this(null, null)
+ {
+ }
+
+ public AsyncMachine(AsyncCallback callback, object state)
+ : base(callback, state)
+ {
+ }
+
+ public T ParameterValue { get; set; }
+ }
+
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P param);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10);
+ public delegate IEnumerable MachineEngineRT(AsyncMachine machine, P1 param1, P2 param2, P3 param3, P4 param4, P5 param5, P6 param6, P7 param7, P8 param8, P9 param9, P10 param10, P11 param11);
+
+ public sealed class AsyncMachine