throw new InvalidOperationException ("Start may not be called on a promise-style task");
SetupScheduler (scheduler);
- Schedule ();
+ Schedule (true);
}
internal void SetupScheduler (TaskScheduler scheduler)
if (IsPromise)
throw new InvalidOperationException ("RunSynchronously may not be called on a promise-style task");
- RunSynchronouslyCore (scheduler);
+ RunSynchronouslyCore (scheduler, true);
}
- internal void RunSynchronouslyCore (TaskScheduler scheduler)
+ internal void RunSynchronouslyCore (TaskScheduler scheduler, bool throwException)
{
SetupScheduler (scheduler);
Status = TaskStatus.WaitingToRun;
if (scheduler.RunInline (this, false))
return;
} catch (Exception inner) {
- throw new TaskSchedulerException (inner);
+ var ex = new TaskSchedulerException (inner);
+ TrySetException (new AggregateException (ex), false, true);
+ if (throwException)
+ throw ex;
+
+ return;
}
- Schedule ();
+ Schedule (throwException);
WaitCore (Timeout.Infinite, CancellationToken.None, false);
}
#endregion
continuations.Add (continuation);
// Retry in case completion was achieved but event adding was too late
- if (IsCompleted) {
- continuations.Remove (continuation);
+ if (IsCompleted && continuations.Remove (continuation)) {
if (!canExecuteInline)
return false;
#endregion
#region Internal and protected thingies
- internal void Schedule ()
+ internal void Schedule (bool throwException)
{
Status = TaskStatus.WaitingToRun;
- scheduler.QueueTask (this);
+ try {
+ scheduler.QueueTask (this);
+ } catch (Exception inner) {
+ var ex = new TaskSchedulerException (inner);
+ TrySetException (new AggregateException (ex), false, true);
+ if (throwException)
+ throw ex;
+ }
}
void ThreadStart ()
return true;
}
- internal bool TrySetException (AggregateException aggregate, bool cancellation)
+ internal bool TrySetException (AggregateException aggregate, bool cancellation, bool observed)
{
if (IsCompleted)
return false;
HandleGenericException (aggregate);
}
+ if (observed)
+ exSlot.Observed = true;
+
return true;
}
return true;
// If the task is ready to be run and we were supposed to wait on it indefinitely without cancellation, just run it
- if (runInline && Status == TaskStatus.WaitingToRun && millisecondsTimeout == Timeout.Infinite && scheduler != null && !cancellationToken.CanBeCanceled)
- scheduler.RunInline (this, true);
+ if (runInline && Status == TaskStatus.WaitingToRun && millisecondsTimeout == Timeout.Infinite && scheduler != null && !cancellationToken.CanBeCanceled) {
+ try {
+ scheduler.RunInline (this, true);
+ } catch (Exception e) {
+ throw new TaskSchedulerException (e);
+ }
+ }
bool result = true;