Merge branch 'BigIntegerParse'
[mono.git] / mcs / class / corlib / System.Threading.Tasks / Task.cs
index 6f9cf654022b7700c35ad9a53908603606339a0f..bb023257b4769978f0db08de9d5a5a4a03119811 100644 (file)
@@ -186,7 +186,7 @@ namespace System.Threading.Tasks
                                throw new InvalidOperationException ("Start may not be called on a promise-style task");
 
                        SetupScheduler (scheduler);
-                       Schedule ();
+                       Schedule (true);
                }
 
                internal void SetupScheduler (TaskScheduler scheduler)
@@ -214,10 +214,10 @@ namespace System.Threading.Tasks
                        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;
@@ -226,10 +226,15 @@ namespace System.Threading.Tasks
                                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
@@ -349,8 +354,7 @@ namespace System.Threading.Tasks
                        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;
 
@@ -380,10 +384,17 @@ namespace System.Threading.Tasks
                #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 ()
@@ -454,7 +465,7 @@ namespace System.Threading.Tasks
                        return true;
                }
 
-               internal bool TrySetException (AggregateException aggregate, bool cancellation)
+               internal bool TrySetException (AggregateException aggregate, bool cancellation, bool observed)
                {
                        if (IsCompleted)
                                return false;
@@ -476,6 +487,9 @@ namespace System.Threading.Tasks
                                HandleGenericException (aggregate);
                        }
 
+                       if (observed)
+                               exSlot.Observed = true;
+
                        return true;
                }
 
@@ -683,8 +697,13 @@ namespace System.Threading.Tasks
                                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;