2008-10-28 12 views
12

Если, как и я, вы дрожите на месте цикла While (True), то вы тоже должны долго и долго думать о лучшем способе реорганизовать его. Я видел несколько различных реализаций, ни один действительно лучше, чем любой другой, например, комбинация делегатов таймера &.Лучший рефакторинг для страшного цикла While (True)

Итак, каким лучшим способом вы столкнулись или видели рефакторинг страшного цикла While (True)?

Редактировать: Как упоминалось в некоторых комментариях, мое намерение состояло в том, чтобы этот вопрос был рефакторингом «бесконечного цикла», например, запуск службы стиля Windows, где единственными условиями остановки были бы OnStop или фатальное исключение.

+0

Я должен был сказать это лучше и подумал о том, чтобы вернуться к этому, но это непрерывный процесс обучения, поэтому я решил оставить вопрос, как это напоминание для меня. :) – 2008-10-30 23:02:26

+0

Если вы «боитесь» пока (правда), вы должны писать очень упрощенные алгоритмы.Большинство современных алгоритмов требуют циклов с несколькими условиями выхода. Самый естественный способ сделать это - иметь внешний бесконечный цикл, а затем несколько условий выхода, которые выходят из цикла. Использование For-loops или while-conditions лучше всего работает, когда у вас есть только одно условие выхода. Хотя это наиболее распространенный случай, вряд ли это универсальная ситуация. – 2017-02-20 19:59:28

ответ

21

Действительно ли нам нужен рефакторинг while (true) Петли? Иногда это стандарт кодирования, и большинство разработчиков привыкли к этой структуре. Если вам нужно много размышлять над тем, как реорганизовать этот код, уверены ли вы, что это хорошая идея реорганизовать его?

Goto Раньше была черная овца в стандартах кодирования. Я встречал алгоритмы, где goto сделал код более читабельным и коротким. Иногда это не стоит рефакторировать (или лучше использовать goto).

С другой стороны, вы можете избежать while (true) большую часть времени.

22

Что в этом такого страшного? Попробуйте найти общее условие перерыва и реорганизовать его как главу цикла. Если это невозможно - отлично.

+0

Yup, yust моя идея ;-). – 2008-10-28 19:11:07

+4

Или рефакторинг, чтобы он был в конце и воспользовался «делать пока». – Torlack 2008-10-28 19:23:26

+0

@Torlack - harhar! – 2008-10-28 19:29:51

12

Замените True тем условием, которое вы собираетесь использовать, чтобы вырваться из цикла.

В случае обслуживания или фонового потока, вы можете использовать:

volatile bool m_shutdown = false; 
void Run() 
{ 
    while (!m_shutdown) 
    { ... } 
} 
+0

Иногда люди делают это для сервисов, где исполнение предназначено для продолжения на неопределенный срок и только сломано OnStop или исключение. Поэтому нет никаких условий. – Grank 2008-10-28 19:17:21

+1

Я думаю, что этот вопрос более ориентирован на полуобязательную практику бесконечного цикла, когда вы на самом деле намерены делать это за конечное количество раз (игнорируя такие вещи, как потоки и т. Д.), Возможно, это просто условие завершения. – 2008-10-28 19:19:35

3

эээ, быть рефакторинга .....

  • Заменить Infinite Loop с бесконечной рекурсии: -)

хорошо, если у вас есть язык, который поддерживает Tail называет ....

13

Когда я встречаю некоторое время (истина) цикл, который говорит мне, либо

  1. условие перерыв не легко проверить в верхней (или нижней) части петли,
    • Есть несколько условий перерыв,
    • или предыдущий программист был слишком ленив, чтобы правильно заколить петлю.

1 и 2 означает, что вы можете также придерживаться время (правда). (Я использую for(;;), но это вещь стиля, на мой взгляд.) Я с другим плакатом, зачем этого бояться? Я боюсь чередующихся петель, которые прыгают через обручи, чтобы заставить петлю прокатиться «правильно».

3

Если вы хотите, чтобы он продолжался бесконечно до полного прерывания программы, я пока не вижу ничего плохого (правда). Недавно я столкнулся с этим сервисом сбора данных .NET, который комбинировал while (true) с thread.sleep, чтобы каждую минуту просыпаться и опросить стороннюю службу данных для новых отчетов. Я рассмотрел рефакторинг с таймером и делегатом, но в конечном итоге решил, что это самый простой и простой способ чтения. В 9 раз из 10 это чистый запах кода, но когда нет условия выхода, зачем усложнять ситуацию?

7

«Бегущая навсегда» ситуация иногда является частью более крупного государственного аппарата. Многие встраиваемые устройства (с непрерывными циклами) на самом деле не запускают навсегда. Они часто имеют несколько режимов работы и будут переключаться между этими режимами.

Когда мы построили контроллеры теплового насоса, был включен режим самотестирования (POST), который работал некоторое время. Затем был предварительный режим экологического сбора, который работал, пока мы не выяснили все зоны и термостаты, а что - нет.

Некоторые инженеры утверждали, что следующим шагом стал цикл «run-forever». Это было не так просто. На самом деле было несколько режимов работы, которые перевернулись и плюхнулись. Было отопление, размораживание, охлаждение, холостой ход и прочее.

Мое предпочтение заключается в том, чтобы обрабатывать цикл «навсегда», как действительно только один режим работы - в какой-то момент в будущем могут быть другие.

someMode= True 
while someMode: 
    try: 
     ... do stuff ... 
    except SomeException, e: 
     log.exception(e) 
     # will keep running 
    except OtherException, e: 
     log.info("stopping now") 
     someMode= False 

В некоторых случаях, ничего мы видели до сих пор не устанавливает someMode в False. Но мне нравится притворяться, что в какой-то будущей версии будет изменение режима.

11

Почему рефакторинг? И что такое «ужасно» в этой конструкции? Он широко используется и хорошо понимается.

Если он не сломался, не исправляйте его.

1

Я не против, когда бесконечный цикл содержится в окне и умирает с окном.

Подумайте о референции Хассельхоффа.

7
#define ever 1 
for (;ever;) 

?

Мех, просто оставить его, как это, в то время (правда), вероятно, так разборчиво, как вы собираетесь получить ..

53

Мое предпочтение было бы

start: 

    // code goes here 

goto start; 

Это наиболее четко выражает намерение. Удачи вам пройти мимо ваших стандартов кодирования. (Интересно, сколько кармы это будет стоить мне).

-2
void whiletrue_sim(void) 
    { 
    //some code 
    whiletrue_sim(); 
    } 

Предупреждение: Ваш стек может быть переполнен, в зависимости от языка, оптимизатора и других факторов.

 Смежные вопросы

  • Нет связанных вопросов^_^