Любой сценарий, в котором Task.ContinueWith(, TaskScheduler.FromCurrentSynchronizationContext()) *не* запускался бы в потоке пользовательского интерфейса?

Мы наблюдаем что-то странное, такой код:

var task = new Task(...); // run in the background, do something lengthy work
task.ContinueWith(..., TaskScheduler.FromCurrentSynchronizationContext());
task.Start();

Вторая задача вызывает событие, которое, в свою очередь, пытается обновить графический интерфейс, и мы получаем ужасное межпоточное исключение.

Проверка Thread.CurrentThread.ManagedThreadId из метода во второй задаче показывает, что на самом деле он не работает в потоке пользовательского интерфейса.

Код, породивший задачи, выполняется в потоке пользовательского интерфейса.

Есть ли какой-нибудь сценарий, когда это пойдет не так?


person Lasse V. Karlsen    schedule 20.03.2013    source источник
comment
Зачем создавать задачу напрямую, а не запускать Task.StartNew?   -  person Panagiotis Kanavos    schedule 20.03.2013
comment
@PanagiotisKanavos, для этого могут быть веские причины (см. blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx), но это не имеет отношения к вопросу.   -  person Matt Smith    schedule 20.03.2013
comment
Ну, я не могу воспроизвести это, и я не сталкивался с этой ситуацией, или контекст становится нулевым, если только вызов для создания задач на самом деле не был сделан в потоке пользовательского интерфейса в первую очередь   -  person Panagiotis Kanavos    schedule 20.03.2013
comment
Первое, что я бы сделал, это проверил, что TaskScheduler.FromCurrentSynchronizationContext возвращает в отладчике. Что вы обнаружите, когда сделаете это?   -  person usr    schedule 20.03.2013
comment
@Lasse, ты нашел причину или решение этой проблемы?   -  person shaibee    schedule 03.11.2015
comment
Да, забыл отметить ответ как принятый. Проблема заключалась в .net 4.0 и нулевом контексте синхронизации, поэтому в какой-то момент создается новый контекст, не связанный с потоком графического интерфейса.   -  person Lasse V. Karlsen    schedule 03.11.2015


Ответы (1)


Предполагая, что вы используете .NET 4.0, существует ошибка, из-за которой System.Threading.SynchronizationContext.Current в основном потоке может стать нулевым, и вы столкнетесь с этой проблемой. Если вы можете легко воспроизвести проблему, первое, что нужно проверить, это проверить, является ли SynchronizationContext.Current нулевым при вызове TaskScheduler.FromCurrentSynchronizationContext().

Подробнее об этой проблеме см. здесь: ">SynchronizationContext.Current имеет значение null в продолжении основного потока пользовательского интерфейса

Ошибка исправлена ​​в .NET 4.5.

person Matt Smith    schedule 20.03.2013