Задать вопрос
@delitme

Как повторить текущую итерацию while C#?

Здравствуйте.

Подскажите пожалуйста как повторить текущую итерацию while C# ?

Т.е. пример

while (условие) {
    код код код код
    код код код код
    
    if (условие) {
        "перезапусить" текущую итерацию заново
    }

    код код код код
    код код код код
}


Нужно чтобы, если выполняется условие if запустить(перезапусить) текущую итерацию по новой. Я к сожалению не смог найти ответ в гугле. Предлагается только continue. Но оно пропустить текущую итерацию и запустить следующую, а мне нужно именно текущую "перезапусить". Возможно ли?

Смотрите ситуация. Идет перебор списка файлов для загрузки с помощью while. Вдруг происходит так что на какой то файл сервер ответил, например 503 ошибкой. Нужно данный файл перекачать по новой в этот же момент. А если continue, то этот файл будет пропущен и мы перейдем к следующему файлу в списке. Или я не прав?
  • Вопрос задан
  • 7707 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
AlekseyNemiro
@AlekseyNemiro
full-stack developer
Зависит от логики. Если, как показано ниже, то можно использовать continue:
int i = 0;
bool b = false;
while (i < 10)
{
	Console.WriteLine("Текущее: {0}", i);
			
	if (i == 5 && !b)
	{
		b = true;
		continue;
	}
			
	i++;
}

В крайнем случае есть goto:
int i = 0; 
bool b = false;
while (i < 10)
{
	again: // точка возврата
	Console.WriteLine("Текущее: {0}", i);
			
	if (i == 5 && !b)
	{
		b = true;
		goto again;
	}
			
	i++;
}

Посмотреть online-пример

Однако не следует злоупотреблять подобными переходами. От обилия операторов goto в коде, у программиста может случиться разрыв мозга, что приведет к неминуемой гибели проекта и его возрождению в новом виде, если, конечно, сам программист не скопытится. Травма та серьезная :-) Если есть возможность, желание и время, лучше изменить логику так, чтобы не приходилось делать такие «прыжки».

Для получения файлов или вообще работы с файлами (ожидание доступа для чтения или удаления, получение данных из сети и т.п.), можно использовать вложенный цикл, который будет пробовать выполнить задачу до тех пор, пока она будет успешно выполнена или не истечет отведенное время на выполнение задачи (или количество попыток):
// пауза между попытками (100 мс)
var interval = new TimeSpan(0, 0, 0, 0, 100); 
// максимальное время ожидания (1 секунда)
var timeout  = new TimeSpan(0, 0, 0, 1); 
while (true)
{
  var totalTime = new TimeSpan(); // счетчик времени
  var заданиеВыполнено = false;

  while(!заданиеВыполнено) // повторять, пока задание не будет выполнено
  {
    try
    {
      // тут код задания
      // если ошибок не будет, то
      заданиеВыполнено = true; // работа цикла будет завершена
    }
    catch
    {
      // если ошибка, делаем паузу
      System.Threading.Thread.Sleep(100);
      // увеличиваем счетчик времени
      totalTime += interval;
      if (totalTime > timeout)
      {
				// превышен таймаут, выходим
				Console.WriteLine("Превышено время ожидания");
				break;
      }
    }
  }
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
@smozhaykin
Используйте, например, очередь. Добавьте в нее все файлы для обработки. В цикле пока очередь не пустая, берите первый элемент и делайте необходимые действия с этим файлом. Если все успешно - удаляйте элемент из очереди. Если ошибка - просто делайте continue (без удаления из очереди) и этот же файл будет обработан на следующей итерации цикла.
Ответ написан
Комментировать
gbg
@gbg Куратор тега Программирование
Любые ответы на любые вопросы
Вопрос на засыпку - чем "текущая" отличается от "следующей"? continue реализует именно то что вам нужно.
Ответ написан
Mrrl
@Mrrl
Заводчик кардиганов
Я бы сделал так:
while (условие) {
    do {
        код код код код
        код код код код
    }while (условие);

    код код код код
    код код код код
}


Но это если "перезапустить текущую итерацию" не требует дополнительного кода. Если требует - поставить вместо do...while бесконечный цикл for(;;) с break незадолго до конца.
Ответ написан
Комментировать
hePPer
@hePPer
Смотрите ситуация. Идет перебор списка файлов для загрузки с помощью while. Вдруг происходит так что на какой то файл сервер ответил, например 503 ошибкой. Нужно данный файл перекачать по новой в этот же момент. А если continue, то этот файл будет пропущен и мы перейдем к следующему файлу в списке. Или я не прав?


и прав и нет. в вашем случае достаточно перед началом цикла завести или переменную счетчик или список закачиваемых файлов. в начале цикла загружать файл и если он загружен устанавливать флаг=загружен, в середине проверять это флаг - если не загружен - то continue, иначе продолжить цикл после условия, где сбросить флаг загрузки, изменить счетчик и произвести манипуляции и файлом. - и никаких костылей.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы