2015-08-12 5 views
2

Справочная информация. Я пишу приложение, которое выполняет итерацию по списку серверов и получает различные сведения о каждой машине. Во время итерации мне нужно обновить различные элементы управления формы (чтобы отобразить сводку полученной информации). Поскольку он выполняет итерацию через список, я вызывал Thread.Sleep(), чтобы дать пользователю время для чтения информации до того, как следующая машина будет опрошена. Ниже мой код:Сохранение пользовательского интерфейса во время Thread.Sleep()

Task TestTask = Task.Factory.StartNew(() => 
      { 
       foreach (String IpAddress in ServersToCheck) 
       { 
        if (IpAddress != String.Empty) 
        { 
         ServerBeingCheckedLabel.Text = IpAddress; 
         if (PingServer(IpAddress) == true) 
         { 
          PingChar_Label.ForeColor = Color.Green; 
          PingChar_Label.Text = "a"; 
          CheckPermissionsAreValid(IpAddress); 
         } 
         else 
         { 
          PingChar_Label.ForeColor = Color.Red; 
          PingChar_Label.Text = "r"; 
          PermChar_Label.ForeColor = Color.Red; 
          PermChar_Label.Text = "r"; 
         } 
        } 
       } 
       Thread.Sleep(10000); 
       this.BackColor = FormBackGroundColor; 
       TestButton.Enabled = true; 
       RunTimer.Enabled = true; 
      }, CancellationToken.None, TaskCreationOptions.None, UiScheduler); 

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

ответ

3

Task.Delay должны удовлетворить ваши потребности.

Изменить

Task.Factory.StartNew(() => 

в

Task.Factory.StartNew(async() => 

и изменить

Thread.Sleep 

в

await Task.Delay 
+0

Это, кажется, работает хорошо, когда последние данные были загружены, но не похоже, чтобы задержать при запуске через пункты перед этим –

+1

Никогда не возражаете, я переместил AWAIT Task.Delay() в другую позицию и теперь, похоже, работает как шарм. Спасибо! –

+0

@ChrisWright, пожалуйста. Не забудьте принять ответ, если ваш вопрос был разрешен. –

0

Task.Delay использования вместо Thread.Sleep фотография This ссылки для получения более подробной информации

4

Если вы передаете UiScheduler как TaskScheduler, тогда эта задача выполняется в потоке пользовательского интерфейса. Так что да, поток пользовательского интерфейса полностью блокируется, когда вы вызываете Thread.Sleep.

Если вы хотите задержать использование await Task.Delay(10000) вместо этого для асинхронной задержки.

Это приведет к возврату задачи с Task.Factory.StartNew a Task<Task>, поскольку она не была построена с учетом асинхронного ожидания, в отличие от Task.Run. Чтобы устранить эту проблему использования Task.Unwrap на возвращаемом Задача:

Task<Task> TestTask = Task.Factory.StartNew(async() => 
{ 
    // ... 
    await Task.Delay(10000); 
    // ... 
}, CancellationToken.None, TaskCreationOptions.None, UiScheduler); 

Task actualTask = TestTask.Unwrap(); 
+0

Большое спасибо за ваш вклад, к сожалению, я могу отметить только один ответ в качестве ответа :( –

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