Кэширование TaskScheduler получено из FromCurrentSynchronizationContext в приложении WPF - PullRequest
2 голосов
/ 21 февраля 2011

Имеет ли смысл хранить / кэшировать TaskScheduler, возвращенный из TaskScheduler.FromCurrentSynchronizationContext, при загрузке приложения WPF и использовать его каждый раз оттуда? Есть ли недостатки такого рода использования?

Под кэшированием я подразумеваю хранить ссылку на TaskScheduler в синглтоне и делать его доступным для всех частей моего приложения, возможно, с помощью контейнера DI / IoC или в худшем случае в голом старом синглтоне.

Ответы [ 2 ]

2 голосов
/ 09 июня 2011

Как говорит Дрю, в этом нет никакого выигрыша в производительности. Но могут быть и другие причины держаться за TaskScheduler.

Одна из причин, по которой вы можете захотеть сделать это, заключается в том, что к тому моменту, когда вам понадобится TaskScheduler, может быть слишком поздно звонить FromCurrentSynchronizationContext, потому что вы больше не сможете быть уверенным, что находитесь в правильном контексте. (Например, возможно, вы можете гарантировать, что ваш конструктор работает в правильном контексте, но у вас нет никаких гарантий относительно того, когда любой из других методов вашего класса вызывается.)

Поскольку единственный способ получить TaskScheduler для SynchronizationContext - это метод FromCurrentSynchronizationContext, вам нужно хранить ссылку на сам TaskScheduler, а не просто захватывать SynchronizationContext.Current во время конструктора. , Но я бы, вероятно, не стал называть это «кешированием», потому что это слово подразумевает, что вы делаете это по соображениям производительности, тогда как на самом деле вы делаете это по необходимости.

Другая возможность состоит в том, что у вас может быть код, который не имеет бизнеса, зная, какой конкретный TaskScheduler он использует, но который все еще должен использовать планировщик, потому что он запускает новые задачи. (Если вы запускаете новые задачи, вы выбираете планировщик, даже если вы этого не понимаете. Если вы явно не выберете, какой планировщик использовать, вы будете использовать стандартный по умолчанию, что не всегда правильно чтобы сделать.) Я написал код, где это так: я написал методы, которые принимают объект TaskScheduler в качестве аргумента и будут использовать его. Так что это еще один сценарий, когда вы можете захотеть сохранить ссылку на планировщик. (Я использовал его, потому что хотел, чтобы определенные операции ввода-вывода происходили в определенном потоке, поэтому я использовал собственный планировщик.)

Сказав все это, синглтон для всего приложения не кажется мне хорошей идеей, потому что он имеет тенденцию усложнять тестирование. И это также означает, что код, захватывающий этот общий планировщик, делает предположения о том, какой планировщик он должен использовать, и это может быть запахом кода.

1 голос
/ 21 февраля 2011

Базовая реализация FromCurrentSynchronizationContext просто создает экземпляр внутреннего класса с именем SynchronizationContextTaskScheduler, который является чрезвычайно легким.Все, что он делает, - кеширует SynchronizationContext, которое он находит при построении, а затем реализация QueueTask просто делает Post для этого SynchronizationContext, чтобы выполнить Task.

Итак, все, что было сказано,Я бы вообще не стал кешировать эти экземпляры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...