| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 | namespace Caliburn.Micro.Core {    using System;    using System.Collections.Generic;    using System.Threading.Tasks;    /// <summary>    /// Manages coroutine execution.    /// </summary>    public static class Coroutine {        static readonly ILog Log = LogManager.GetLog(typeof(Coroutine));        /// <summary>        /// Creates the parent enumerator.        /// </summary>        public static Func<IEnumerator<IResult>, IResult> CreateParentEnumerator = inner => new SequentialResult(inner);        /// <summary>        /// Executes a coroutine.        /// </summary>        /// <param name="coroutine">The coroutine to execute.</param>        /// <param name="context">The context to execute the coroutine within.</param>        /// /// <param name="callback">The completion callback for the coroutine.</param>        public static void BeginExecute(IEnumerator<IResult> coroutine, CoroutineExecutionContext context = null, EventHandler<ResultCompletionEventArgs> callback = null) {            Log.Info("Executing coroutine.");            var enumerator = CreateParentEnumerator(coroutine);            IoC.BuildUp(enumerator);            if (callback != null) {                ExecuteOnCompleted(enumerator, callback);            }            ExecuteOnCompleted(enumerator, Completed);            enumerator.Execute(context ?? new CoroutineExecutionContext());        }        /// <summary>        /// Executes a coroutine asynchronous.        /// </summary>        /// <param name="coroutine">The coroutine to execute.</param>        /// <param name="context">The context to execute the coroutine within.</param>        /// <returns>A task that represents the asynchronous coroutine.</returns>        public static Task ExecuteAsync(IEnumerator<IResult> coroutine, CoroutineExecutionContext context = null) {            var taskSource = new TaskCompletionSource<object>();            BeginExecute(coroutine, context, (s, e) => {                if (e.Error != null)                    taskSource.SetException(e.Error);                else if (e.WasCancelled)                    taskSource.SetCanceled();                else                    taskSource.SetResult(null);            });            return taskSource.Task;        }        static void ExecuteOnCompleted(IResult result, EventHandler<ResultCompletionEventArgs> handler) {            EventHandler<ResultCompletionEventArgs> onCompledted = null;            onCompledted = (s, e) => {                result.Completed -= onCompledted;                handler(s, e);            };            result.Completed += onCompledted;        }        /// <summary>        /// Called upon completion of a coroutine.        /// </summary>        public static event EventHandler<ResultCompletionEventArgs> Completed = (s, e) => {            if(e.Error != null) {                Log.Error(e.Error);            }            else if(e.WasCancelled) {                Log.Info("Coroutine execution cancelled.");            }            else {                Log.Info("Coroutine execution completed.");            }        };    }}
 |