Esempio n. 1
0
        protected async CoyoteTasks.Task <TResult> GetResultAsync <TResult>(CoyoteTasks.Task <TResult> task, int millisecondsDelay = 5000)
        {
            if (Debugger.IsAttached)
            {
                millisecondsDelay = 500000;
            }

            if (this.IsSystematicTest)
            {
                // The TestEngine will throw a Deadlock exception if this task can't possibly complete.
                await task;
            }
            else
            {
                await CoyoteTasks.Task.WhenAny(task, CoyoteTasks.Task.Delay(millisecondsDelay));
            }

            if (task.IsFaulted)
            {
                // unwrap the AggregateException so unit tests can more easily
                // Assert.Throws to match a more specific inner exception.
                throw task.Exception.InnerException;
            }

            Assert.True(task.IsCompleted, string.Format("Task timed out after '{0}' milliseconds", millisecondsDelay));
            return(await task);
        }
Esempio n. 2
0
 /// <summary>
 /// Waits for the task to complete execution and returns the result.
 /// </summary>
 public TResult WaitTaskCompletes<TResult>(CoyoteTasks.Task<TResult> task)
 {
     // TODO: return immediately if completed without errors.
     var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();
     IO.Debug.WriteLine("<Task> '{0}' is waiting task '{1}' with result type '{2}' to complete from task '{3}'.",
         callerOp.Name, task.Id, typeof(TResult), Task.CurrentId);
     callerOp.OnWaitTask(task.UncontrolledTask);
     return task.UncontrolledTask.Result;
 }
Esempio n. 3
0
        public CoyoteTasks.Task <TResult> ScheduleFunction <TResult>(Func <CoyoteTasks.Task <TResult> > function, Task predecessor,
                                                                     CancellationToken cancellationToken)
        {
            // TODO: support cancellations during testing.
            this.Assert(function != null, "The task cannot execute a null function.");

            ulong operationId = this.Runtime.GetNextOperationId();
            var   op          = new TaskOperation(operationId, this.Scheduler);

            this.Scheduler.RegisterOperation(op);
            op.OnEnabled();

            var task = new Task <Task <TResult> >(() =>
            {
                try
                {
                    // Update the current asynchronous control flow with the current runtime instance,
                    // allowing future retrieval in the same asynchronous call stack.
                    CoyoteRuntime.AssignAsyncControlFlowRuntime(this.Runtime);

                    OperationScheduler.StartOperation(op);
                    if (predecessor != null)
                    {
                        op.OnWaitTask(predecessor);
                    }

                    CoyoteTasks.Task <TResult> resultTask = function();
                    this.OnWaitTask(operationId, resultTask.UncontrolledTask);
                    return(resultTask.UncontrolledTask);
                }
                catch (Exception ex)
                {
                    // Report the unhandled exception and rethrow it.
                    this.ReportUnhandledExceptionInOperation(op, ex);
                    throw;
                }
                finally
                {
                    IO.Debug.WriteLine("<ScheduleDebug> Completed operation '{0}' on task '{1}'.", op.Name, Task.CurrentId);
                    op.OnCompleted();
                }
            });

            Task <TResult> innerTask = task.Unwrap();

            // Schedule a task continuation that will schedule the next enabled operation upon completion.
            innerTask.ContinueWith(t => this.Scheduler.ScheduleNextEnabledOperation(), TaskScheduler.Current);

            IO.Debug.WriteLine("<CreateLog> Operation '{0}' was created to execute task '{1}'.", op.Name, task.Id);
            this.Scheduler.ScheduleOperation(op, task.Id);
            task.Start();
            this.Scheduler.WaitOperationStart(op);
            this.Scheduler.ScheduleNextEnabledOperation();

            return(new CoyoteTasks.Task <TResult>(this, innerTask));
        }
Esempio n. 4
0
        public CoyoteTasks.Task<CoyoteTasks.Task<TResult>> WhenAnyTaskCompletesAsync<TResult>(IEnumerable<CoyoteTasks.Task<TResult>> tasks)
        {
            this.Assert(tasks != null, "Cannot wait for a null array of tasks to complete.");
            this.Assert(tasks.Count() > 0, "Cannot wait for zero tasks to complete.");

            var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();
            this.Assert(callerOp != null,
                "Uncontrolled task '{0}' invoked a when-any operation.",
                Task.CurrentId.HasValue ? Task.CurrentId.Value.ToString() : "<unknown>");
            callerOp.OnWaitTasks(tasks, waitAll: false);

            CoyoteTasks.Task<TResult> result = null;
            foreach (var task in tasks)
            {
                if (task.IsCompleted)
                {
                    result = task;
                    break;
                }
            }

            return CoyoteTasks.Task.FromResult(result);
        }