protected static void InlineIfPossibleOrElseQueue(Task task, bool needsProtection) { if (needsProtection) { if (!task.MarkStarted()) { return; } } else { task.m_stateFlags |= 65536; } try { if (task.m_taskScheduler.TryRunInline(task, false)) { return; } task.m_taskScheduler.InternalQueueTask(task); } catch (Exception ex) { if (ex is ThreadAbortException && (task.m_stateFlags & 134217728) != 0) { return; } TaskSchedulerException schedulerException = new TaskSchedulerException(ex); task.AddException((object)schedulerException); task.Finish(false); } }
protected static void InlineIfPossibleOrElseQueue(Task task, bool needsProtection) { Contract.Requires(task != null); Contract.Assert(task.m_taskScheduler != null); // Set the TASK_STATE_STARTED flag. This only needs to be done // if the task may be canceled or if someone else has a reference to it // that may try to execute it. if (needsProtection) { if (!task.MarkStarted()) { return; // task has been previously started or canceled. Stop processing. } } else { task.m_stateFlags |= Task.TASK_STATE_STARTED; } // Try to inline it but queue if we can't try { if (!task.m_taskScheduler.TryRunInline(task, taskWasPreviouslyQueued: false)) { task.m_taskScheduler.InternalQueueTask(task); } } catch (Exception e) { // Either TryRunInline() or QueueTask() threw an exception. Record the exception, marking the task as Faulted. // However if it was a ThreadAbortException coming from TryRunInline we need to skip here, // because it would already have been handled in Task.Execute() if (!(e is ThreadAbortException && (task.m_stateFlags & Task.TASK_STATE_THREAD_WAS_ABORTED) != 0)) // this ensures TAEs from QueueTask will be wrapped in TSE { TaskSchedulerException tse = new TaskSchedulerException(e); task.AddException(tse); task.Finish(false); } // Don't re-throw. } }