Я прочел this question от Noseratio, который показывает поведение, где TaskScheduler.Current
не такой же после того, как он уже закончил свою работу.Ожидание не возобновляет контекст после операции async?
Ответ гласит:
Если нет актуальной задачей выполняется, то
TaskScheduler.Current
такая же, какTaskScheduler.Default
Что верно. Я уже видел это here:
TaskScheduler.Default
- Возвращает экземпляр
ThreadPoolTaskScheduler
TaskScheduler.Current
- Если вызывается из выполняющегося задания будет возвращать
TaskScheduler
из в настоящее время выполнения задачи- Если вызывается из любого другого места вернутся
TaskScheduler.Default
Но потом я подумал, если так, давайте сделать создать фактическое Task
(а не только Task.Yield()
) и протестируйте его:
async void button1_Click_1(object sender, EventArgs e)
{
var ts = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Factory.StartNew(async() =>
{
MessageBox.Show((TaskScheduler.Current == ts).ToString()); //True
await new WebClient().DownloadStringTaskAsync("http://www.google.com");
MessageBox.Show((TaskScheduler.Current == ts).ToString());//False
}, CancellationToken.None, TaskCreationOptions.None,ts).Unwrap();
}
Первый информационный блок «True», se конд является "False"
Вопрос:
Как вы можете видеть, я создал реальную задачу.
Я могу понять, почему первый MessageBox дает True
. То becuase из:
Если вызывается из выполняющегося задания будет возвращать TaskScheduler в исполняемой в данный момент задачи
И эта задача действительно есть ts
, который является отправленным TaskScheduler.FromCurrentSynchronizationContext()
Но почему контекст не сохранен на второй MessageBox? Для меня это было непонятно из ответа Стефана.
Дополнительная информация:
Если я пишу, вместо (второго MessageBox):
MessageBox.Show((TaskScheduler.Current == TaskScheduler.Default).ToString());
Это выход true
. Но почему ?
Отличный вопрос, но что, если 'task scheduler! = Контекст синхронизации'? – AgentFire
Хороший случай для жесткого правила: никогда не принимайте 'TaskScheduler.Текущий' то, что вы думаете, это :) Гарантируется, что вы передали 'Factory.StartNew' для области действия задачи лямбда (которая является' Func 'в вашем случае и возвращается, когда она попадает в первый' await'). Любое другое поведение следует рассматривать как детали реализации. –
Noseratio