2015-03-17 2 views
0

У меня довольно общий вопрос с циклом C# while.C# во время использования цикла

Этот код должен продолжать выполняться только после того, как сеанс RDP действительно отключен.

Когда свойство Connected изменено на 0, это означает, что соединение сеанса RDP действительно завершено. Когда свойство равно 1, оно все еще подключено и соединение еще не завершено.

Кто-нибудь видит что-то внутренне плохое в отношении этого кода? Есть ли лучший способ сделать это?

private void Reconnect() 
{ 
    rdp1.Disconnect(); // force the RDP session to disconnect 
    while (rdp1.Connected == 1) // true as long as RDP is still connected 
    { 
     // do nothing 
    } 
    rdp1.Connect(); // execute this code after while loop is broken 
} 

/****************************************** ********************/

Вот последний код, который я использовал для ответа Джеймса. Счетчик достаточен в качестве таймаута для моей цели.

  int i = 0; 
      rdp1.Disconnect(); 
      while (rdp1.Connected == 1) 
      { 
       if (i == 1000 * 10) break; 
       else Thread.Sleep(100); 
       i++; 
      } 
      rdp1.Connect(); 
+1

Есть ли вообще что-либо, что может привести к булеву тесту на провал? Возможно, сервер занят и никогда не обходит выполнение функции разъединения, или команда теряется где-то в повреждении данных ... Пользователям может понадобиться способ вырваться из него. ИДК. –

+0

Да, я думаю, что это мое беспокойство, что если объект rdp1 по какой-то причине потерпел неудачу, а изменение состояния не было обнаружено, пользователю понадобился бы какой-то перерыв. Может быть, просто тайм-аут или попытка/уловка могут работать. –

+0

Ответ Джеймса имеет хорошую информацию; Я все еще думаю, что вам нужен способ, чтобы пользователь сказал, что что-то случилось, вызвало меня. –

ответ

1

Вы должны сделать что-то в теле цикла, или он будет потреблять весь ваш процессор (по крайней мере для одного ядра). Обычно в этом типе цикла вы некоторое время будете спать, используя System.Threading.Thread.Sleep(100) или что-то в этом роде. Sleep берет количество миллисекунд, чтобы подождать, прежде чем снова проверить условие while. В идеале, объект RDP имел бы мьютекс или событие или что-то, что вы могли бы просто заблокировать до тех пор, пока оно не будет отключено, но меня это не удивило бы, если бы они это оставили.

РЕДАКТИРОВКА: Как указал Бен, всегда хорошо иметь выход из петли. Что-то вроде этого (вашего указанного ответа будет зависеть от скорости процессора, которые могли бы нарушить в будущем, когда процессоры гораздо быстрее):

DateTime stop = DateTime.UtcNow.AddSeconds(30); 
while (rdp1.Connected) 
{ 
    if (DateTime.UtcNow > stop) throw new ApplicationException ("RDP disconnect timeout!"); 
    System.Threading.Thread.Sleep (100); 
} 

Конечно, вы, вероятно, хотите, чтобы указать таймаут с константой, только для чтения TimeSpan или динамически настраиваемый TimeSpan, а не волшебное число, и вы должны, вероятно, иметь конкретный класс исключений для этого случая.

+1

(Спящий или уступающий для * любого * времени - например, 0 мс, что почти похоже на «доходность» - в целом будет достаточно нетостер ЦП.) – user2864740

+0

Прохладный, у меня был Thread.Sleep (100); в нем первоначально. Я добавлю, что вернусь и, по крайней мере, есть способ вытащить пользователя. –

+1

@ user2864740: Да, технически это правильно в простом случае.Однако на практике вы часто не знаете, насколько дорогой тест цикла (если он получает значение свойства - он может делать _anything_), и если у вас много циклов, подобных этому, а также другие программы, конкурирующие за CPU, ожидающий более миллисекунды, вероятно, мудр. В любом случае вам редко нужен цикл, чтобы так быстро сломаться. На самом деле иногда вам нужно немного поспать _after_ цикл выходит, потому что вещи не всегда действительно закончены, когда говорят, что они (например, File.Delete). – James

1

Установите тайм-аут для целей

private void Reconnect() 
{ 
    timeOut = false; 
    new System.Threading.Thread(new System.Threading.ThreadStart(setTimeout)).Start(); 
    rdp1.Disconnect(); 
    while (rdp1.Connected == 1 && !timeOut); 
    rdp1.Connect(); 
} 

bool timeOut = false; 

void setTimeout() 
{ 
    System.Threading.Thread.Sleep(7000); 
    timeOut = true; 
} 
+0

Это будет потреблять весь процессор в основном потоке до 7 секунд, а затем попытается подключиться, даже если объект не был отключен (т. Е. Если прошло семь секунд и соединение все еще было активным). Это не похоже на хорошую идею. – James

+0

Он подключается к какой-либо другой нити и хочет подождать самой основной нити. Теперь включите флаг в другом потоке. Так в чем проблема? – Sayka

+0

Я думаю, что вопрос был более сосредоточен вокруг, если цикл while был правильным, было опасно не делать ничего внутри цикла. Я не обязательно искал лучшее решение, просто логика звучит с циклом while. Я добавил быстрый счетчик времени, который будет достаточным на данный момент. –

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