Комментарии 15
Подобные конструкции требуют много ресурсов процессора
Похожим примером может быть следующая конструкция:
Данный подход на гораздо лучше предыдущего, но все же не идеален.
Так как идеально то?
Выбор того или иного решения напрямую зависит от конкретной задачи — в статье мы рассмотрели только распространенные подходы. Если возникает проблема с синхронизацией флага 'proceed', то стоит воспользоваться эксклюзивной блокировкой или «сигналингом», который обычно предпочтительней блокировок, потому что так рабочему потоку не нужно лишний раз просыпаться и проверять флаги или какие-либо источники данных.
Я это говорю к тому, что вы привели примеры, как сделать плохо и не привели примера, как сделать хорошо.
Или вы имеет в виду, что вот это и есть хорошо?
Или вы имеет в виду, что вот это и есть хорошо?
Обычно реализуется при помощи методов класса Thread: Sleep() и Join(), метода EndInvoke() асинхронных делегатов или при помощи тасков (Task) и их механизмов ожидания.
Наивный вопрос: а почему нельзя было сделать так, чтобы при любом создании объекта Thread поток брался бы из пула потоков (раз уж это быстрее)?
> Потокам из пула невозможно назначить имя
Можно (Thread.CurrentThread.Name = "..."), но оно будет сброшено при рециклинге.
Можно (Thread.CurrentThread.Name = "..."), но оно будет сброшено при рециклинге.
Спасибо за статью! Действительно много полезной информации о многопоточности .NET в одном месте. В избранное однозначно :)
(ошибся уровнем)
Вот хороший бесплатный курс (дополнение к теме):
Академия Microsoft: Параллельные вычисления и многопоточное программирование.
Разобрана работа многих алгоритмов в разных режимах.
Академия Microsoft: Параллельные вычисления и многопоточное программирование.
Разобрана работа многих алгоритмов в разных режимах.
вот вопрос: что лучше использовать для запуска долгого потока, с временем жизни равным времени жизни приложения? помню когда я писал реализацию 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); });
И будет работать. Но это если вы хотите сломать мозг кому-нибудь)
> Исправить данную проблему можно, переписав код следующим образом:
> 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» и пара примеров в статье очень похожи на те, что по ссылке.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Основы многопоточности в .NET Framework