TaskScheduler - 执行延续
TaskScheduler - executing continuations
在阅读了一些关于 TaskScheduler
(good article here) 的内容后,发现 TaskScheduler
可以:
计划任务 - 通过使用 QueueTask
方法,在上面的示例中仅 Post
s 任务执行到选定的 SynchronizationContext
通过与当前 运行 框架 (SynchronizationContext
) 关联的较低级别的调度程序安排延续。
2. 是否与 Task
的 CotninueWith
方法有任何关系?我显然理解 1.,但不明白 2. 对于 TaskScheduler
是如何成立的。 TaskScheduler
的什么方法会发生这种情况?
Schedule continuations through the lower-level scheduler associated
with the currently running framework (SynchronizationContext).
我觉得你有点混淆了。您可以使用给定的 TaskScheduler
并对其执行延续,而不是相反。这正是您分享的 post 中的这个片段所做的:
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var tf = Task.Factory;
blendedImage.ContinueWith(_ =>
{
pictureBox1.Image = blendedImage.Result;
}, ui);
它告诉 Task.ContinueWith
更早地使用 UI TaskScheduler
(通过调用 TaskScheduler.FromCurrentSynchronizationContext()
提供)以便在特定上下文中调用延续,这次是 UI 消息循环。
如果您真的想深入了解细节,当您将 TaskScheduler
传递给 ContinueWith
时,它最终会将其传递给名为 StandardTaskContinuation
的 class它具有以下 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;
}
}
在阅读了一些关于 TaskScheduler
(good article here) 的内容后,发现 TaskScheduler
可以:
计划任务 - 通过使用
QueueTask
方法,在上面的示例中仅Post
s 任务执行到选定的SynchronizationContext
通过与当前 运行 框架 (
SynchronizationContext
) 关联的较低级别的调度程序安排延续。
2. 是否与 Task
的 CotninueWith
方法有任何关系?我显然理解 1.,但不明白 2. 对于 TaskScheduler
是如何成立的。 TaskScheduler
的什么方法会发生这种情况?
Schedule continuations through the lower-level scheduler associated with the currently running framework (SynchronizationContext).
我觉得你有点混淆了。您可以使用给定的 TaskScheduler
并对其执行延续,而不是相反。这正是您分享的 post 中的这个片段所做的:
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var tf = Task.Factory;
blendedImage.ContinueWith(_ =>
{
pictureBox1.Image = blendedImage.Result;
}, ui);
它告诉 Task.ContinueWith
更早地使用 UI TaskScheduler
(通过调用 TaskScheduler.FromCurrentSynchronizationContext()
提供)以便在特定上下文中调用延续,这次是 UI 消息循环。
如果您真的想深入了解细节,当您将 TaskScheduler
传递给 ContinueWith
时,它最终会将其传递给名为 StandardTaskContinuation
的 class它具有以下 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;
}
}