Ну так всё правильно. Await/async — это по сути реализация сопроцедур и здесь мы видим описание кооперативной многозадачности. Теоретически через них можно было бы даже попробовать порешать классические задачи сопроцедур… Но с учётом их не особо эффективной реализации в C# наверное всё же нет смысла.
Ну, в том виде, в котором вы привели код, оно вовсе не будет компилировать.
Ай, не то скопировал… Да и в статье тоже самое… Ужас какой. )))
Если у входного потока был установлен SyncronizationContext, или в параметрах Task.Run был передан вот такой аргумент TaskScheduler.FromCurrentSynchronizationContext(), то по окончании исполнения CalсSomething исполнение неявного коллбека с ProcessResult будет добавлено в очередь к этому SyncronizationContext-у, и исполнено на входном потоке.
Если нет — исполнение ProcessResult будет выполнено на первом попавшемся треде, не обязательно UI.
Так вот, у WinForms у входного потока SyncronizationContext есть, поэтому ProcessResult отсылается исполняться на UI.
Я в курсе) И я как раз поэтому везде и указывал что Handler вызываем из UI потока — тогда он точно туда и вернётся (если не укажем иного, а оно нам и не надо). При вызове же из не UI потока ситуация уже естественно совсем другая, но в таком случае на мой взгляд уже и вообще вся эта схема не требуется, т.к. в потоках без цикла сообщений мы свободны использовать более просты и удобные методы (см. самое начало статье).
В .NET для этого существовало средство и до async/await, это ThreadPool + SyncronizationContext. Именно последний отвечает за то, чтобы (опять же, цитата)
Конечно) И даже не только это средство. Я и написал об этом в начале, что полный набор инструментов для асинхронного программирования есть во многих языках и давным давно. Но это всё без вскусного синтаксического сахара… )))
Просто применение async/await никакого переключения в исходный поток не делает
Тогда в каком потоке по вашему будет исполняться ProcessResult из этого
private async void Handler(Params prms)
{
var r = await new Task(() => CalcSomething(prms););
ProcessResult(r);
}
примера? Считаем что Handler вызвали из UI потока.
Ай, не то скопировал… Да и в статье тоже самое… Ужас какой. )))
Я в курсе) И я как раз поэтому везде и указывал что Handler вызываем из UI потока — тогда он точно туда и вернётся (если не укажем иного, а оно нам и не надо). При вызове же из не UI потока ситуация уже естественно совсем другая, но в таком случае на мой взгляд уже и вообще вся эта схема не требуется, т.к. в потоках без цикла сообщений мы свободны использовать более просты и удобные методы (см. самое начало статье).
По теме: а ведь полезная штучка для дома вышла, а не просто фан!
Конечно) И даже не только это средство. Я и написал об этом в начале, что полный набор инструментов для асинхронного программирования есть во многих языках и давным давно. Но это всё без вскусного синтаксического сахара… )))
Тогда в каком потоке по вашему будет исполняться ProcessResult из этого
примера? Считаем что Handler вызвали из UI потока.