2015-03-05 2 views
0

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

Как я могу выполнить ожидание в другом потоке (если это даже проблема), чтобы остановить пользовательский интерфейс от замораживания?

Вот мой код:

 while (floor > elevator.currentFloor) 
     { 
      elevator.currentFloor++; 
      changeStatus(elevator); 
      currentFloorLbl.Text = "Current Floor: " + elevator.currentFloor; 
      System.Threading.Thread.Sleep(500); 
     } 
+0

Вам нужно запустить весь цикл while в другой ветке, возможно, используя BackgroundWorker или используя Task.Factory.StartNew (...). – failedprogramming

+0

Ошибка при неудачном прогоне. – Aron

+0

Могу ли я иметь пример, пожалуйста? –

ответ

1

Предполагая, что вы используете Win Forms, переместить свой код в System.Windows.Forms.Timer. Если нет, используйте appropriate .NET timer.

+0

David, хорошее решение; однако я бы предоставил ему пример. –

+0

Да, пожалуйста, пример будет хорошим. –

+0

Это будет сложным для ОП, учитывая, что 'CurrentFloorLbl', скорее всего, является элементом пользовательского интерфейса. Придерживайтесь однопоточности, используйте .net 4.5 – Aron

1
while (floor > elevator.currentFloor) 
    { 
     elevator.currentFloor++; 
     changeStatus(elevator); 
     currentFloorLbl.Text = "Current Floor: " + elevator.currentFloor; 
     await Task.Delay(500); 
    } 

Как вы можете видеть, мы используем await Task.Delay(500) вместо Thread.Sleep(500). Оба они достигают того же, что останавливает выполнение вашего кода на 500 мс.

Разница в том, что Thread.Sleep(500) - это то, что мы называем блокирующим вызовом. Он сообщает вашему потоку (поток пользовательского интерфейса, поток, который рисует на вашем экране), чтобы заснуть. Это означает, что ваш пользовательский интерфейс не может быть обновлен в течение этого времени.

С другой стороны, await означает, что здесь есть код, который расскажет вам, когда это будет сделано. До его завершения выйдите на улицу и сделайте что-нибудь еще (например, обновите пользовательский интерфейс). Task.Delay(500) означает, что через 500 мс скажите кому-то, что вы «сделаны».

Разница заключается в том, что в течение этих 500 мс это решение позволит вашему потоку пользовательского интерфейса выполнять все служебные работы, такие как обновление экрана, реагирование на мышь и т. Д., В то время как ваш код имеет очень важный поток пользовательского интерфейса. праздник (оставляя ваш пользовательский интерфейс закрытым для бизнеса).

+0

Несомненно, вы хотите использовать Task.Delay (500) вместо Task.Подождите (500)? Тем не менее, я не верю, что это сработает. – failedprogramming

+0

@failedprogramming вы можете быть правы> _ Aron

+0

Вы должны объяснить свой код OP. Вы уже много писали в комментариях о том, как все упростить для OP, но вы тут же приложили нулевые усилия. –

0

Хорошо, спасибо Арону, мне пришлось сделать метод в асинхронном методе, чтобы использовать его в ожидании - и теперь он работает! Я могу «подождать», обновляя свой интерфейс. Вот отредактированный код:

async void move(int floor) 
    { 
     DateTime now = DateTime.Now; 
     TimeSpan duration; 
     while (floor > elevator.currentFloor) 
     { 
      await Task.Delay(500); 
      elevator.currentFloor++; 
      changeStatus(elevator); 
      currentFloorLbl.Text = "Current Floor: " + elevator.currentFloor; 
      duration = DateTime.Now - now; 
      timeLbl.Text = "Time elapsed: " + duration.TotalMilliseconds.ToString() + "ms"; 
     } 
Смежные вопросы