public static int WaitAny(Task[] tasks, int millisecondsTimeout, CancellationToken cancellationToken) { if (tasks == null) { throw new ArgumentNullException("tasks"); } if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } CheckForNullTasks(tasks); if (tasks.Length > 0) { var evt = new ManualResetEventSlim(); var slot = new ManualEventSlot(evt); bool result = false; try { for (int i = 0; i < tasks.Length; i++) { var t = tasks[i]; if (t.IsCompleted) { return(i); } t.ContinueWith(slot); } if (!(result = evt.Wait(millisecondsTimeout, cancellationToken))) { return(-1); } } finally { if (!result) { foreach (var t in tasks) { t.RemoveContinuation(slot); } } evt.Dispose(); } } int firstFinished = -1; for (int i = 0; i < tasks.Length; i++) { var t = tasks[i]; if (t.IsCompleted) { firstFinished = i; break; } } return(firstFinished); }
public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } bool result = true; if (!IsCompleted) { // If the task is ready to be run and we were supposed to wait on it indefinitely, just run it if (Status == TaskStatus.WaitingToRun && millisecondsTimeout == -1 && scheduler != null) { Execute(); } if (!IsCompleted) { var evt = new ManualResetEventSlim(); var slot = new ManualEventSlot(evt); try { ContinueWith(slot); result = evt.Wait(millisecondsTimeout, cancellationToken); } finally { if (!result) { RemoveContinuation(slot); } evt.Dispose(); } } } if (IsCanceled) { throw new AggregateException(new TaskCanceledException(this)); } var exception = Exception; if (exception != null) { throw exception; } return(result); }