2014-02-17 3 views
1

В моей программе есть цикл, который останавливается только если пользователь нажимает определенную кнопку. Теперь я хочу дать пользователю определенное количество времени, чтобы нажать кнопку. Я меняю цвет кнопки, чтобы показать пользователю, что кнопка останова включена.Как приостановить цикл на C#, чтобы дождаться взаимодействия с пользователем?

this.button.Focus(); 

this.button.BackColor = Color.Green; 

System.Threading.Thread.Sleep(2000); 

// now the loop continues and the button changes its color 
this.button.BackColor = Color.White; 

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

ответ

0

Кажется, что ваш UI замерзает, и вы не можете увидеть cahgnes.Instead попробовать это, сделать ваш метод async затем использовать await

public async void SomeMethod() 
{ 
    this.button.BackColor = Color.Green; 

    await Task.Delay(2000); 

    this.button.BackColor = Color.White; 
} 
+0

Это не дождитесь, когда кнопка будет нажата. – Servy

0

Вы не должны использовать Thread.Sleep() как он вешает свой пользовательский интерфейс.

Попробуйте:

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 
timer1.Interval=2000; 
timer1.Tick += new System.EventHandler(timer1_Tick); 
timer1.Start(); 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    //do whatever you want 
    this.button.BackColor = Color.White; 

    //Stop Timer 
    timer1.Stop(); 
} 
1

Нить вы Усыплено тот же поток, который отвечает за разработку приложения. Следовательно, вызов Sleep здесь просто прекратит обработку приложения. Это определенно не то, что вы хотите сделать.

Лучшим способом решения этой проблемы является использование объекта Timer. Остановите обработку, измените цвет кнопки и настройте Timer на огонь за 2 секунды. Если кнопка нажата раньше, остановите таймер, иначе, если произойдет событие таймера, перезапустите обработку. Этот метод позволит приложению продолжать работать во время второго окна.

1

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

К счастью, ключевое слово await делает это намного проще, чем другие методы.

Сначала мы просто создать вспомогательный метод для создания задачи, которая будет завершена, когда кнопка нажата:

public static Task WhenClicked(this Button button) 
{ 
    var tcs = new TaskCompletionSource<bool>(); 
    EventHandler handler = null; 
    handler = (s, e) => 
    { 
     tcs.TrySetResult(true); 
     button.Click -= handler; 
    }; 
    button.Click += handler; 
    return tcs.Task; 
} 

Теперь мы легко можем ждать до тех пор, как 2-х секунд не прошло, или кнопка clicked:

public async void Bar() 
{ 
    this.button.Focus(); 

    this.button.BackColor = Color.Green; 

    await Task.WhenAny(Task.Delay(2000), button.WhenClicked()); 

    // now the loop continues and the button changes its color 
    this.button.BackColor = Color.White; 
} 
+0

Лучший ответ. Хотя, почему 'async void', а не' async Task'? – Noseratio

+0

@Noseratio Поскольку я предполагал, что это будет метод ввода верхнего уровня, обработчик события для ... чего-то. На самом деле не похоже что-то сочинить с другим методом. Если бы это было так, то да, он должен вернуть «Задачу». – Servy

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