2014-11-24 4 views
0

Я запускаю приложение Windows Forms, которое необходимо обновить GUI, и поэтому имеют, чтобы использовать планировщик, который исходит из текущего контекста синхронизации. Код: TaskScheduler.FromCurrentSynchronizationContext()Измените планировщик из TaskScheduler.FromCurrentSynchronizationContext() для модульных тестов

При написании модульных тестов этот планировщик необходимо переключить, потому что мы хотим использовать собственный планировщик, который запускает материал одновременно и синхронно в тесте. Существуют альтернативы (инъекция, ManualResetEvent), но это уродливо, и мы не хотим этого.

Можно изменить TaskScheduler.Default, используя отражение, чтобы перезаписать приватную переменную, и это здорово, но нет очевидного способа сделать то же самое с TaskScheduler.FromCurrentSynchronizationContext().

Итак, как вы это делаете?

+2

Как инъекция зависимости уродлива? Это звучит для меня нелепо. Для меня это звучит так, как вы пытаетесь достичь (отражение для перезаписи частной переменной) - это то, что уродливо. Лучший подход - это ввести фабрику, которая возвращает ваш планировщик или вставлять сам планировщик. –

+0

Вы называете DI странным, но скорее используете отражение, чтобы извлечь личную переменную внутри класса? Я думаю, что у вас это смешанное :) –

+0

Да, хорошо, уродливая вещь, о которой я говорил, был ManualResetEvent. Инъекция, безусловно, выглядит лучше, но остается актуальный вопрос: как изменить планировщик в TaskScheduler.FromCurrentSynchronizationContext()? – imbageek

ответ

2

Одна вещь, которая может работать в сценарии модульного тестирования, заключается в создании TestSynchronizationContext, который наследуется от SynchronizationContext и назначает его SynchronizationContext.SetSynchronizationContext(). Ваш класс TestSynchronizationContext переопределит метод Post, чтобы вместо этого перенаправить на метод Send, заставив его работать синхронно.

Для справки можно найти источники here.

+0

Великий человек. Это именно то, что я искал. – imbageek

+0

Омг. Я не может форматировать мой ответ здесь, но вот код для SyncContext не используется Threadpool для работы: 'InvokeNowSynchronizationContext общественного класса: SynchronizationContext { общественного переопределения недействительного сообщение (SendOrPostCallback d, объект состояния) { d. Invoke (состояние); } public override void Send (SendOrPostCallback d, состояние объекта) { d.Invoke (состояние); } } ' – imbageek