理解TaskScheduler.Current的行为 [英] Understanding the behavior of TaskScheduler.Current

查看:319
本文介绍了理解TaskScheduler.Current的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个简单的WinForms应用程序:

Here's a simple WinForms app:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            var ts = TaskScheduler.FromCurrentSynchronizationContext();
            await Task.Factory.StartNew(async () =>
            {
                Debug.WriteLine(new
                {
                    where = "1) before await",
                    currentTs = TaskScheduler.Current,
                    thread = Thread.CurrentThread.ManagedThreadId,
                    context = SynchronizationContext.Current
                });

                await Task.Yield(); // or await Task.Delay(1)

                Debug.WriteLine(new
                {
                    where = "2) after await",
                    currentTs = TaskScheduler.Current,
                    thread = Thread.CurrentThread.ManagedThreadId,
                    context = SynchronizationContext.Current
                });

            }, CancellationToken.None, TaskCreationOptions.None, scheduler: ts).Unwrap();
        }
    }
}

调试输出中(点击该按钮时):

The debug ouput (when the button is clicked):


{ where = 1) before await, currentTs = System.Threading.Tasks.SynchronizationContextTaskScheduler, thread = 9, context = System.Windows.Forms.WindowsFormsSynchronizationContext }
{ where = 2) after await, currentTs = System.Threading.Tasks.ThreadPoolTaskScheduler, thread = 9, context = System.Windows.Forms.WindowsFormsSynchronizationContext }

的问题:为什么 TaskScheduler.Current SynchronizationContextTaskScheduler 更改为<$ C C> ThreadPoolTask​​Scheduler $后等待吗?

The question: Why is TaskScheduler.Current changing from SynchronizationContextTaskScheduler to ThreadPoolTaskScheduler after await here?

这主要表现该行为 TaskCreationOptions.HideScheduler 计谋延续,这是意想不到的和不受欢迎的,在我看来,

This essentially exhibits the behavior TaskCreationOptions.HideScheduler for await continuation, which is unexpected and undesirable, in my opinion.

这个问题已经触发了我的另一个问题:

This question has been triggered by another question of mine:

AspNetSynchronizationContext伺机在ASP​​.NET 的延续。

推荐答案

如果没有实际的任务的执行,那么 TaskScheduler.Current 是一样的 TaskScheduler.Default 。换句话说, ThreadPoolTask​​Scheduler 实际上既充当线程池的任务调度程序的的值,意思是没有当前的任务调度程序。

If there is no actual task being executed, then TaskScheduler.Current is the same as TaskScheduler.Default. In other words, ThreadPoolTaskScheduler actually acts both as the thread pool task scheduler and the value meaning "no current task scheduler".

异步委托的第一部分计划明确使用了 SynchronizationContextTaskScheduler ,并运行与UI线程上既是任务调度和同步内容。任务调度转发委托给同步上下文。

The first part of the async delegate is scheduled explicitly using the SynchronizationContextTaskScheduler, and runs on the UI thread with both a task scheduler and synchronization context. The task scheduler forwards the delegate to the synchronization context.

计谋捕捉它的上下文,它抓住了同步的情况下(而不是任务调度程序),并使用该syncctx恢复。因此,该方法继续被张贴到syncctx,这在UI线程上执行它。

When the await captures its context, it captures the synchronization context (not the task scheduler), and uses that syncctx to resume. So, the method continuation is posted to that syncctx, which executes it on the UI thread.

在延续了UI线程上运行,它的表现非常相似的事件处理程序;委托是直接执行,而不是包裹在一个任务。如果检查 TaskScheduler.Current 的button1_Click 的开始,你会发现它也是 ThreadPoolTask​​Scheduler

When the continuation runs on the UI thread, it behaves very similarly to an event handler; the delegate is executed directly, not wrapped in a task. If you check TaskScheduler.Current at the beginning of button1_Click, you'll find it is also ThreadPoolTaskScheduler.

顺便说一句,我建议你把这种行为(执行代表直接,不是裹着任务)作为一个实现细节。

BTW, I recommend you treat this behavior (executing delegates directly, not wrapped in tasks) as an implementation detail.

这篇关于理解TaskScheduler.Current的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆