Подтвердить что ты не робот

Какова концептуальная разница между SynchronizationContext и TaskScheduler

Стивен Тууб в блоге, который

Оба SynchronizationContext и TaskScheduler - это абстракции, которые представляют собой "планировщик", то, на что вы даете некоторую работу, и это определяет, когда и где выполнять эту работу. Есть много разных формы планировщиков. Например, ThreadPool является планировщиком: вы вызовите ThreadPool.QueueUserWorkItem для предоставления делегата для запуска, который делегат попадает в очередь, а один из потоков ThreadPools в конечном итоге собирает и запускает этот делегат. В вашем пользовательском интерфейсе также есть планировщик: насос сообщений.

Итак System.Reactive.Concurrency.EventLoopScheduler, Dispatcher, ThreadPool, TaskScheduler, SyncrhonizationContext и Реализации Rejective Extensions - это все "планировщики" в этом смысле,

В чем разница между ними?

Почему все это было необходимо? Я думаю, что получаю EventLoop, Dispatcher, ThreadPool. IScheduler также хорошо объяснены.
Но TaskScheduler и SyncrhonizationContext все еще не понятны мне.

Отличная статья Стивена Клири объясняет SyncrhonizationContext, и я думаю, что поняла. Почему тогда нам нужен TaskScheduler, неясно.

Пожалуйста, объясните или укажите источник.

4b9b3361

Ответ 1

Каждая платформа имеет собственный "планировщик" , и вокруг них есть свои собственные абстракции. например WinForms использует насос сообщений. WPF использует еще один насос сообщений, абстрагированный в "Диспетчер". ThreadPool - это еще один "планировщик" , абстрагированный в "ThreadPool". Эти (и некоторые другие) являются планировщиками более низкого уровня.

Задача и TaskScheduler хотели бы, чтобы пользователю задачи не приходилось думать о планировании задач на этих более низких уровнях (вы можете, конечно, абстрактным образом). Вы должны иметь возможность запустить задачу, и эмбиент "планировщик" должен позаботиться об этом. Например, TaskFactory.StartNew(()=>{LengthyOperation()}) должен работать независимо от того, на какой платформе я работаю. То, в которое входит SynchronizationContext. Он знает, что планировщики нижнего уровня задействованы в текущей запущенной структуре. Это передается вместе с TaskScheduler, и планировщик может как планировать задачи (возможно, на ThreadPool), так и планировать продолжение через планировщик нижнего уровня, связанный с текущим запуском фреймворка (см. SynchronizationContext), чтобы поддерживать требования синхронизации. например хотя вы хотите, чтобы ваша задача выполнялась в ThreadPool, вы можете продолжить продолжение в потоке пользовательского интерфейса.

Важно знать, что TaskScheduler является абстракцией нескольких других планировщиков. Это не единственная причина, по которой она существует, но одна из причин этой "лишней" абстракции ".

Ответ 2

Хотя, как указано,

Оба SynchronizationContext и TaskScheduler - это абстракции, которые представляют собой "планировщик"

IMO, степень абстракции (и, следовательно, API) различается. SynchronizationContext - это более общий API в том смысле, что Post/Send принимает делегат простого метода.

С другой стороны, TaskScheduler является абстракцией, характерной для TPL, поэтому он предлагает такие методы, как QueueTask, который имеет дело с объектом Task. Использование контекста синхронизации вместо планировщика задач (т.е. С конкретной реализацией TPL SynchronizationContext) сделало бы более утомительным работу с планированием задач (и, конечно же, это был бы слабо типизированный API в контексте TPL). Итак, дизайнеры TPL выбрали модель абстрактного API-планировщика, который имеет смысл для TPL (что цель абстракции в любом случае - правильно?) - конечно, чтобы устранить пробел, FCL содержит внутренний класс SynchronizationContextTaskScheduler, который является реализацией реализации TaskScheduler оболочки SynchronizationContext.

SynchronizationContext был представлен в .NET 2.0, в то время как TPL был представлен в .NET 4. Интересно подумать о том, какие дизайнеры FCL выбрали бы, если бы последовательность была другой, например, что если TPL существовала во время .NET 2.0. IMO, TaskScheduler можно было бы использовать вместо SynchrinizationContext, моделируя delgates как задачу в конкретной специализации.