TaskScheduler — выполнение продолжений

Немного почитав о TaskScheduler (хорошая статья здесь), получается, что TaskScheduler может:

  1. Запланировать задачи — с помощью метода QueueTask, который в приведенном выше примере просто выполняет задачу Posts для выбранных SynchronizationContext

  2. Запланируйте продолжение через планировщик более низкого уровня, связанный с запущенной в данный момент платформой (SynchronizationContext).

2. как-то связан с CotninueWith методом Task? Я, очевидно, понимаю 1., но не понимаю, как 2. верно для TaskScheduler. В каком методе TaskScheduler это произойдет?


person user4205580    schedule 19.11.2015    source источник
comment
Ну, есть Task.ContinueWith перегрузки, которые берут TaskScheduler, так что продолжение запланировано этим планировщиком... вы об этом думаете?   -  person Jon Skeet    schedule 19.11.2015


Ответы (1)


Запланируйте продолжение с помощью планировщика более низкого уровня, связанного с запущенной в данный момент платформой (SynchronizationContext).

Я думаю, вы немного перепутали. Вы можете использовать заданный TaskScheduler и выполнить на нем продолжение, а не наоборот. Это именно то, что делает этот фрагмент из поста, которым вы поделились:

var ui = TaskScheduler.FromCurrentSynchronizationContext(); 
var tf = Task.Factory; 

blendedImage.ContinueWith(_ => 
{ 
    pictureBox1.Image = blendedImage.Result; 
}, ui); 

Он говорит Task.ContinueWith использовать пользовательский интерфейс TaskScheduler (который был предоставлен вызовом TaskScheduler.FromCurrentSynchronizationContext()) ранее, чтобы вызвать продолжение в определенном контексте, на этот раз это цикл сообщений пользовательского интерфейса.

Если вы действительно хотите перейти к деталям, когда вы передаете TaskScheduler в ContinueWith, он в конечном итоге передает его классу с именем StandardTaskContinuation, который имеет следующий метод Run, который в конечном итоге вызывает TaskScheduler.InternalTaskQueue:

internal void ScheduleAndStart(bool needsProtection)
{
    if (needsProtection)
    {
        if (!this.MarkStarted())
        {
            return;
        }
    }
    else
    {
        this.m_stateFlags |= 65536;
    }
    if (Task.s_asyncDebuggingEnabled)
    {
        Task.AddToActiveTasks(this);
    }
    if (AsyncCausalityTracer.LoggingOn && 
       (this.Options & (TaskCreationOptions)512) == TaskCreationOptions.None)
    {
        AsyncCausalityTracer.TraceOperationCreation(
            CausalityTraceLevel.Required, this.Id, "Task: " +
            ((Delegate)this.m_action).Method.Name, 0uL);
    }
    try
    {
        this.m_taskScheduler.InternalQueueTask(this);
    }
    catch (ThreadAbortException exceptionObject)
    {
        this.AddException(exceptionObject);
        this.FinishThreadAbortedTask(true, false);
    }
    catch (Exception arg_93_0)
    {
        TaskSchedulerException ex = new TaskSchedulerException(arg_93_0);
        this.AddException(ex);
        this.Finish(false);
        if ((this.Options & (TaskCreationOptions)512) == TaskCreationOptions.None)
        {
            this.m_contingentProperties.m_exceptionsHolder.MarkAsHandled(false);
        }
        throw ex;
    }
}
person Yuval Itzchakov    schedule 19.11.2015