private async Task RunSingleTask(ITaskDefinition <TIdentifier> singleTaskDefinition, PreconditionEvaluator <TIdentifier> preconditionEvaluator, ImmutableList <ISchedule <TIdentifier> > schedules, ImmutableList <TaskPrecondition <TIdentifier> > preconditions, SessionRunResult <TIdentifier> sessionRunResult, DateTime startTime, Guid runId)
        {
            var taskSchedule = schedules.Single(candidateSchedule => EqualityComparer <TIdentifier> .Default.Equals(candidateSchedule.TaskDefinitionId, singleTaskDefinition.Id));
            var history      = historyReader.GetNew();

            history.StartTime        = startTime;
            history.TaskDefinitionId = singleTaskDefinition.Id;
            history.RunId            = runId;
            var runResult = default(SingleTaskRunResult);

            var failingPrecondition = await preconditionEvaluator.GetFailingPrecondition(singleTaskDefinition, preconditions);

            var allPreconditionsPassed = string.IsNullOrEmpty(failingPrecondition);

            if (allPreconditionsPassed)
            {
                try
                {
                    runResult = await runner.RunAsync(singleTaskDefinition);
                }
                catch (Exception e)
                {
                    await faultHandler.HandleAsync(singleTaskDefinition, e);

                    runResult = new SingleTaskRunResult
                    {
                        Succeeded = false,
                        Remarks   = e.Message,
                    };
                }
                finally
                {
                    if (taskSchedule.IsOnDemand)
                    {
                        onDemandQueueManager.DeQueue(taskSchedule.TaskDefinitionId);
                    }
                }
                history.Remarks = runResult.Remarks;
                history.Status  = runResult.Succeeded ? RunHistoryStatuses.CompletedSuccessfully : RunHistoryStatuses.Failed;
            }
            else
            {
                history.Remarks = $"Precondition '{failingPrecondition}' failed";
                history.Status  = RunHistoryStatuses.PreconditionPreventedRun;
            }
            history.EndTime = taskSchedule.LastRun = DateTime.Now;

            sessionRunResult.Histories = sessionRunResult.Histories.Add(history);
            sessionRunResult.Schedules = sessionRunResult.Schedules.Add(taskSchedule);
        }