這裏有一個簡單的WinForms應用程序:瞭解TaskScheduler.Current的行爲
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();
}
}
}
調試輸出中(該按鈕被點擊時):
{ 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
到ThreadPoolTaskScheduler
之後await
在這裏?
這實質上表現出行爲TaskCreationOptions.HideScheduler
爲await
延續,這在我看來是意想不到的和不受歡迎的。
AspNetSynchronizationContext and await continuations in ASP.NET:
這個問題已經被我的另一個問題引發的。
這是我以爲它的工作原理,但不想在沒有更多信息的情況下發表評論。 +1。 –
我明白了,顯然這是'TaskAwaiter'的工作原理。國際海事組織(IMO),他們爲「流動」TaskScheduler.Current而設計的這一設計頗爲令人困惑:通常情況下,這並不是你所期望的。 – Noseratio
同意; 'TaskScheduler.Current'在設計時考慮了動態並行性,以便子任務從父任務繼承調度器。這種默認行爲對異步任務來說很混亂,這就是爲什麼我堅持在每個'StartNew'和'ContinueWith'中明確指定調度器的原因。 –