Я часто вижу, как упоминается, что Thread.Sleep();
не следует использовать, но я не могу понять, почему это так. Если это Thread.Sleep();
может вызвать проблемы, есть ли какие-либо альтернативные решения с тем же результатом, которые были бы безопасными?
например.
while(true)
{
doSomework();
i++;
Thread.Sleep(5000);
}
еще один:
while (true)
{
string[] images = Directory.GetFiles(@"C:\Dir", "*.png");
foreach (string image in images)
{
this.Invoke(() => this.Enabled = true);
pictureBox1.Image = new Bitmap(image);
Thread.Sleep(1000);
}
}
c#
multithreading
sleep
Burimi
источник
источник
goto:
то, что, вероятно, есть лучшее решение ваших проблем, чемSleep
.goto
, что больше похоже на запах кода, чем на запах дизайна. Нет ничего плохого в том, что компилятор вставляетgoto
s в ваш код: компьютер не запутается. НоThread.Sleep
не совсем то же самое; компиляторы не вставляют этот вызов, и это имеет другие негативные последствия. Но да, общее мнение о том, что его использовать неправильно, потому что почти всегда есть лучшее решение, безусловно, верно.sleep()
код (или тесты), умирает щенокОтветы:
Проблемы , связанные с вызовом
Thread.Sleep
ARE объясняется довольно лаконично здесь :Предпочтительное решение: WaitHandles
Самая частая ошибка - это использование
Thread.Sleep
конструкции while ( демонстрация и ответ , хорошая запись в блоге )РЕДАКТИРОВАТЬ:
Я хотел бы улучшить свой ответ:
источник
СЦЕНАРИЙ 1 - дождитесь завершения асинхронной задачи: я согласен с тем, что WaitHandle / Auto | ManualResetEvent следует использовать в сценарии, когда поток ожидает завершения задачи в другом потоке.
СЦЕНАРИЙ 2 - синхронизация цикла while: однако, как грубый механизм синхронизации (while + Thread.Sleep) отлично подходит для 99% приложений, которые НЕ требуют точного знания , когда заблокированный поток должен «проснуться» *. Аргумент, который он принимает 200 тыс. Циклов для создания потока также недопустимы - поток цикла синхронизации необходимо создать в любом случае, а 200 тыс. Циклов - это просто еще одно большое число (скажите мне, сколько циклов для открытия вызовов файла / сокета / базы данных?).
Итак, если while + Thread.Sleep работает, зачем все усложнять? Только юристы по синтаксису будут практичными !
источник
Я хотел бы ответить на этот вопрос с точки зрения политики кодирования, которая может быть полезна, а может и нет. Но особенно когда вы имеете дело с инструментами, предназначенными для 9-5 корпоративных программистов, люди, которые пишут документацию, склонны использовать такие слова, как «не следует» и «никогда», чтобы означать «не делайте этого, если вы действительно не знаете, что вы делаем и зачем ».
Еще парочка моих любимых в мире C # - это то, что они говорят вам «никогда не вызывать lock (this)» или «никогда не вызывать GC.Collect ()». Эти два случая настоятельно заявлены во многих блогах и официальной документации, а ИМО являются полной дезинформацией. На каком-то уровне эта дезинформация служит своей цели, поскольку она удерживает новичков от занятий, которые они не понимают, до полного исследования альтернатив, но в то же время затрудняет поиск РЕАЛЬНОЙ информации через поисковые системы, которые все Кажется, что они указывают на статьи, в которых говорится не делать чего-либо, но не дают ответа на вопрос «почему бы и нет?».
С политической точки зрения, все сводится к тому, что люди считают «хорошим дизайном» или «плохим дизайном». Официальная документация не должна диктовать дизайн моего приложения. Если есть действительно техническая причина, по которой вы не должны вызывать sleep (), то в документации IMO должно быть указано, что это нормально называть его в определенных сценариях, но, возможно, предлагать некоторые альтернативные решения, которые не зависят от сценария или более подходят для другого сценарии.
Ясно, что вызов "sleep ()" полезен во многих ситуациях, когда крайние сроки четко определены в терминах реального времени, однако существуют более сложные системы для ожидания и сигнализации потоков, которые следует рассмотреть и понять, прежде чем вы начнете бросать спать ( ) в свой код, а добавление ненужных операторов sleep () в код обычно считается тактикой новичков.
источник
Это цикл 1) .spinning и 2) .polling ваших примеров, против которого люди предостерегают , а не часть Thread.Sleep (). Я думаю, что Thread.Sleep () обычно добавляется, чтобы легко улучшить код, который вращается или находится в цикле опроса, поэтому он просто связан с «плохим» кодом.
Вдобавок люди делают такие вещи, как:
где переменная inWait не доступна поточно-ориентированным способом, что также вызывает проблемы.
Программисты хотят видеть потоки, управляемые конструкциями Events, Signaling и Locking, и когда вы это сделаете, у вас не будет необходимости в Thread.Sleep (), а также исчезнут опасения по поводу безопасного для потоков доступа к переменным. Например, не могли бы вы создать обработчик событий, связанный с классом FileSystemWatcher, и использовать событие для запуска второго примера вместо цикла?
Как упомянул Андреас Н., прочтите « Потоки в C #» Джо Альбахари , это действительно действительно хорошо.
источник
Thread.Sleep()
другую функцию и вызвать ее в цикле while?Спящий режим используется в тех случаях, когда независимые программы, которые вы не контролируете, могут иногда использовать обычно используемый ресурс (например, файл), к которому вашей программе требуется доступ при запуске, и когда ресурс используется этими другие программы ваша программа заблокирована от ее использования. В этом случае, когда вы обращаетесь к ресурсу в своем коде, вы помещаете свой доступ к ресурсу в try-catch (чтобы поймать исключение, когда вы не можете получить доступ к ресурсу), и вы помещаете это в цикл while. Если ресурс свободен, сон никогда не вызывается. Но если ресурс заблокирован, вы спите в течение определенного времени и снова пытаетесь получить доступ к ресурсу (вот почему вы зацикливаетесь). Однако имейте в виду, что вы должны установить какой-то ограничитель на цикл, чтобы он не был потенциально бесконечным.
источник
У меня есть вариант использования, который я не совсем вижу здесь, и я буду утверждать, что это веская причина использовать Thread.Sleep ():
В консольном приложении, выполняющем задания очистки, мне нужно сделать большое количество довольно дорогостоящих вызовов базы данных к базе данных, совместно используемой тысячами одновременно работающих пользователей. Чтобы не забивать БД и часами исключать других, мне понадобится пауза между вызовами, порядка 100 мс. Это не связано с таймингом, а просто с предоставлением доступа к БД для других потоков.
Тратить 2000–8000 циклов на переключение контекста между вызовами, выполнение которых может занять 500 мс, не представляет опасности, как и наличие 1 МБ стека для потока, который выполняется как единственный экземпляр на сервере.
источник
Thread.Sleep
в однопоточном одноцелевом консольном приложении вроде того, которое вы описываете, совершенно нормально.Я согласен со многими здесь, но я также думаю, что это зависит от обстоятельств.
Недавно я сделал такой код:
Это была простая функция анимации, и я ее использовал
Thread.Sleep
.Мой вывод: если он работает, используйте его.
источник
Для тех из вас, кто не видел ни одного веского аргумента против использования Thread.Sleep в СЦЕНАРИИ 2, действительно есть один - выход из приложения задерживается циклом while (СЦЕНАРИЙ 1/3 просто глуп, поэтому не заслуживает большего. упоминая)
Многие, кто притворяются знающими, кричащими Thread.Sleep is evil, не упомянули единственную вескую причину для тех из нас, кто требовал практической причины не использовать его - но вот оно, спасибо Питу - Thread.Sleep зло (можно легко избежать с помощью таймера / обработчика)
источник
Thread.Sleep
это не причина (новый поток и непрерывный цикл while)! вы можете просто удалитьThread.Sleep
строку - и вуаля: программа тоже не выйдет ...