#c# #silverlight #windows-phone-7
#c# #silverlight #windows-phone-7
Вопрос:
Пока что, за время моего опыта разработки приложений для Windows Phone 7, я заметил, что существуют разные способы выполнения действия в асинхронном потоке.
- Система.Многопоточность.Нитки
- Система.ComponentModel.BackgroundWorker
- Система.Многопоточность.ThreadPool.QueueUserWorkItem()
Я не смог увидеть никакой ощутимой разницы между этими методами (кроме того, что первые два более прослеживаемы).
Есть ли что-нибудь, что вы, ребята, учитываете перед использованием любого из этих методов? Какой из них вы бы предпочли и почему?
Комментарии:
1. Вы имеете в виду, кроме очевидного обсуждения потоков против ThreadPools?
2.Возможно, это зависит от того, что вы пытаетесь сделать, вы перечислили 3 очень разные модели потоков (basic, UI и managed pool), читали ли вы MSDN и т.д… albahari.com/threading msdn.microsoft.com/en-us/library/aa645740 (v =против71).aspx
3. @Lloyd На самом деле Bgw выполняется поверх пула потоков, а в SL потоки обычно связаны с пользовательским интерфейсом, поэтому 2 == 3
4. Что ж, предпочтение каждого из них при разработке Windows Phone является предметом этого вопроса.
5. @Henk хммм, верно, но это все еще 3 отдельные модели потоков, даже в Silverlight.
Ответ №1:
На вопрос вроде бы дан ответ, но в ответах немного не хватает деталей (IMO).
Давайте рассмотрим каждый из них по очереди.
Система.Многопоточность.Нитки
Все потоки (во всяком случае, в среде CLR) в конечном итоге представлены этим классом. Однако вы, вероятно, включили это для запроса, когда мы могли бы захотеть создать экземпляр самостоятельно.
Ответ встречается редко. Обычно повседневной рабочей лошадкой для отправки фоновых задач является Threadpool
. Однако есть некоторые обстоятельства, при которых мы хотели бы создать наш собственный поток. Обычно такой поток будет работать большую часть времени выполнения приложения. Он провел бы большую часть своей жизни в блокировке при некотором дескрипторе ожидания. Иногда мы сигнализируем об этом дескрипторе, и он оживает, чтобы сделать что-то важное, но затем он снова переходит в спящий режим. Мы не используем рабочий элемент Threadpool для этого, потому что мы не одобряем идею о том, что он может стоять в очереди за большим набором невыполненных задач, некоторые из которых сами по себе (возможно, непреднамеренно) могут быть заблокированы при каком-то другом ожидании.
Система.ComponentModel.BackgroundWorker
Это удобная оболочка класса для рабочего элемента ThreadPool. Этот класс предназначен только для разработчика, ориентированного на пользовательский интерфейс, которому иногда требуется использовать фоновый поток. Его события, отправляемые в потоке пользовательского интерфейса, упрощают его использование.
Система.Многопоточность.ThreadPool.QueueUserWorkItem
Это повседневная рабочая лошадка, когда у вас есть какая-то работа, которую вы хотите выполнить в фоновом потоке. Это устраняет затраты на выделение и освобождение отдельных потоков для выполнения некоторой задачи. Это ограничивает количество экземпляров потоков, чтобы предотвратить поглощение слишком большого количества доступных ресурсов слишком большим количеством операций, пытающихся выполняться параллельно.
QueueUserWorkItem
Это мой предпочтительный вариант для вызова фоновых операций.
Комментарии:
1. Хороший ответ. Просто хотел добавить, что ThreadPool.QueueUserWorkItem и BackgroundWorker оба работают с фоновыми потоками. Это означает, что потоки будут немедленно завершены при завершении работы приложения. Если вам нужно выполнить работу в другом потоке, и она должна завершиться независимо от того, выходит ли пользователь из приложения, тогда вам нужно напрямую использовать класс Thread и установить для IsBackground значение false .
2. @calum: Хороший момент, однако я не уверен, что произойдет, если приложение будет закрыто в WP7 / Silverlight. Хотя
IsBackground
свойствоThread
класса поддерживается в соответствии с документацией, «между ними нет разницы в поведении».3. ммм … это может на самом деле объяснить некоторую случайную загрузку данных, которую я заметил. Думаю, мне нужно запустить несколько тестов, чтобы увидеть, что происходит на самом деле. Спасибо за предупреждение.
Ответ №2:
Возможно, это зависит от того, что вы пытаетесь сделать, вы перечислили 3 очень разные модели потоков.
- Базовые потоки
- Разработан для приложений с отдельным потоком пользовательского интерфейса.
- Управляемый пул потоков
Читали ли вы MSDN и т.д…
http://www.albahari.com/threadin
Http://msdn.microsoft.com/en-us/library/aa645740 (v = против71).aspx
Комментарии:
1. Что ж, предпочтение каждого из них при разработке Windows Phone является предметом этого вопроса.
2. Я бы все же задался вопросом, что вы делаете, выполняя какую-то форму взаимодействия клиент-сервер, которая может не обновлять пользовательский интерфейс, загружая данные в фоновом режиме, которые обновляют пользовательский интерфейс, или запуская вызов метода, который может быть запущен при наличии свободного потока (возможно, не транзакционного) и может обновлять, а может и не обновлять пользовательский интерфейс.
3. Является ли обновление пользовательского интерфейса серьезной проблемой? Можем ли мы не использовать Deployment. Диспетчер для обновления пользовательского интерфейса в любом фоновом потоке?
4. Пользовательский интерфейс Silverlights в значительной степени зависит от ресурсов, поэтому любая операция, требующая ресурсов из пользовательского интерфейса, может повлиять и будет влиять на его производительность. Если у вас есть базовое LOB-приложение, то это может не быть проблемой при повторных вызовах пользовательского интерфейса, однако, если у вас динамический пользовательский интерфейс, который зависит от пользовательского ввода и анимации, тогда вам нужно будет посмотреть, как и когда вы управляете потоковыми ресурсами.
5. Кстати, когда я говорю «зависящий от ресурсов», я имею в виду, что он ограничен Silverlight framework и CLR по сравнению с Windows .Net Framework.
Ответ №3:
Вы не указываете «зачем», но
- Базовый поток — довольно дорогой, не для небольших заданий
- Backgroundworker — в основном для работы с пользовательским интерфейсом Progressbar
- ThreadPool — для небольших независимых заданий
Я думаю, что TPL не поддерживается в SL, к сожалению.
Комментарии:
1. Если под TPL вы имеете в виду ThreadPool, я думаю, что это работает в Windows Phone.
2. Нет, TPL = Параллельная библиотека задач
3. О да, я должен удвоить эту жалость 🙂
Ответ №4:
Фоновый рабочий процесс, как правило, лучше использовать, когда ваш пользовательский интерфейс нуждается в обновлении по мере продвижения вашего потока, потому что он обрабатывает вызов функций обратного вызова (таких как обратный вызов OnProgress) в потоке пользовательского интерфейса, а не в фоновом потоке. Два других не выполняют эту работу. Это зависит от вас, чтобы сделать это.