protected async CoyoteTasks.Task WaitAsync(CoyoteTasks.Task 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); }
/// <summary> /// Waits for the task to complete execution. The wait terminates if a timeout interval /// elapses or a cancellation token is canceled before the task completes. /// </summary> public bool WaitTaskCompletes(CoyoteTasks.Task task) { // TODO: return immediately if completed without errors. // TODO: support timeouts and cancellation tokens. var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>(); IO.Debug.WriteLine("<Task> '{0}' is waiting task '{1}' to complete from task '{2}'.", callerOp.Name, task.Id, Task.CurrentId); callerOp.OnWaitTask(task.UncontrolledTask); return true; }
public CoyoteTasks.Task ScheduleFunction(Func <CoyoteTasks.Task> 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>(() => { 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 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 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(this, innerTask)); }
protected async CoyoteTasks.Task WaitAsync(CoyoteTasks.Task task, int millisecondsDelay = 5000) { millisecondsDelay = GetExceptionTimeout(millisecondsDelay); if (this.SchedulingPolicy is SchedulingPolicy.None) { await CoyoteTasks.Task.WhenAny(task, CoyoteTasks.Task.Delay(millisecondsDelay)); } else { // The TestEngine will throw a Deadlock exception if this task can't possibly complete. await task; } 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); }
public CoyoteTasks.Task<CoyoteTasks.Task> WhenAnyTaskCompletesAsync(IEnumerable<CoyoteTasks.Task> 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 result = null; foreach (var task in tasks) { if (task.IsCompleted) { result = task; break; } } return CoyoteTasks.Task.FromResult(result); }