Как стать автором
Обновить

Комментарии 15

Подобные конструкции требуют много ресурсов процессора

Похожим примером может быть следующая конструкция:

Данный подход на гораздо лучше предыдущего, но все же не идеален.


Так как идеально то?
Выбор того или иного решения напрямую зависит от конкретной задачи — в статье мы рассмотрели только распространенные подходы. Если возникает проблема с синхронизацией флага 'proceed', то стоит воспользоваться эксклюзивной блокировкой или «сигналингом», который обычно предпочтительней блокировок, потому что так рабочему потоку не нужно лишний раз просыпаться и проверять флаги или какие-либо источники данных.
Я это говорю к тому, что вы привели примеры, как сделать плохо и не привели примера, как сделать хорошо.

Или вы имеет в виду, что вот это и есть хорошо?
Обычно реализуется при помощи методов класса Thread: Sleep() и Join(), метода EndInvoke() асинхронных делегатов или при помощи тасков (Task) и их механизмов ожидания.
Наивный вопрос: а почему нельзя было сделать так, чтобы при любом создании объекта Thread поток брался бы из пула потоков (раз уж это быстрее)?
(а) Потому что пул потоков конечен
(б) Потому что объекты Thread нужны для низкоуровневого управления многопоточностью. Раз уж вы туда полезли — значит, знаете, что делаете.
> Потокам из пула невозможно назначить имя

Можно (Thread.CurrentThread.Name = "..."), но оно будет сброшено при рециклинге.
Спасибо за статью! Действительно много полезной информации о многопоточности .NET в одном месте. В избранное однозначно :)
Да, книга что надо +1.
Stephen Cleary пишет очень толковые вещи. Я постоянный читатель статей с его сайта. Вся информация структурированная и читается легко.
вот вопрос: что лучше использовать для запуска долгого потока, с временем жизни равным времени жизни приложения? помню когда я писал реализацию MTProto на C# с использованием TPL.Dataflow мне нужен был бесконечный метод который бы читал из сокета данные. я пробовал делать это на тасках, async all the way, все дела, но тогда я упирался в запуск этих задач в бесконечном цикле. Красивого способа я не нашёл, в итоге остановился на обычном таймере, который запускал чтение из сокета.
> await Task.Factory.StartNew(async () => { await Task.Delay(1000); });

> Исправить данную проблему можно, переписав код следующим образом:
> await Task.Run(async () => { await Task.Delay(1000); });

Ну, в данном конкретном случае лучше исправить просто на «await Task.Delay(1000);», конечно. Ещё, кстати, можно написать:

await await Task.Factory.StartNew(async () => { await Task.Delay(1000); });

И будет работать. Но это если вы хотите сломать мозг кому-нибудь)
Ещё один шикарный ресурс про сабж: Threading in C#.
Кстати, могу ошибаться, но табличка «A Comparison of Locking Constructs» и пара примеров в статье очень похожи на те, что по ссылке.
Кстати, могу ошибаться, но табличка «A Comparison of Locking Constructs» и пара примеров в статье очень похожи на те, что по ссылке.

Оттуда и есть. При этом у Joe Albahari на сайте ссылки ещё на переводы: Chinese | Czech | Persian | Russian | Japanese.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий