Подтвердить что ты не робот

Подождите несколько секунд, не блокируя выполнение пользовательского интерфейса.

Я хотел бы подождать несколько секунд между двумя инструкциями, но БЕЗ блокировки выполнения.

Например, Thread.Sleep(2000) это плохо, потому что он блокирует выполнение.

Идея заключается в том, что я вызываю метод, а затем я жду X секунд (например, 20) при прослушивании события. В конце 20 секунд я должен выполнить некоторую операцию в зависимости от того, что произошло за 20 секунд.

4b9b3361

Ответ 1

Я думаю, что вы находитесь за Task.Delay. Это не блокирует поток, как Sleep, и это означает, что вы можете сделать это, используя один поток, используя модель программирования async.

async Task PutTaskDelay()
{
    await Task.Delay(5000);
} 

private async void btnTaskDelay_Click(object sender, EventArgs e)
{
    await PutTaskDelay();
    MessageBox.Show("I am back");
}

Ответ 2

Я использую:

private void WaitNSeconds(int segundos)
{
    if (segundos < 1) return;
    DateTime _desired = DateTime.Now.AddSeconds(segundos);
    while (DateTime.Now < _desired) {
         System.Windows.Forms.Application.DoEvents();
    }
}

Ответ 3

Это хороший пример для использования другого потока:

// Call some method
this.Method();

Task.Factory.StartNew(() =>
{
    Thread.Sleep(20000);

    // Do things here.
    // NOTE: You may need to invoke this to your main thread depending on what you're doing
});

Приведенный выше код ожидает .NET 4.0 или выше, в противном случае попробуйте:

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
    Thread.Sleep(20000);

    // Do things here
}));

Ответ 4

Решение Omar достойно *, если вы не можете обновить свою среду до .NET 4.5, чтобы получить доступ к API-интерфейсу async и ждать. Тем не менее, здесь есть одно важное изменение, которое должно быть сделано для того, чтобы избежать низкой производительности. Небольшая задержка должна быть добавлена ​​между вызовами Application.DoEvents(), чтобы предотвратить чрезмерное использование ЦП. Добавив

Thread.Sleep(1);

перед вызовом Application.DoEvents() вы можете добавить такую ​​задержку (1 миллисекунду) и запретить приложению использовать все доступные для него циклы процессора.

private void WaitNSeconds(int seconds)
{
    if (seconds < 1) return;
    DateTime _desired = DateTime.Now.AddSeconds(seconds);
    while (DateTime.Now < _desired) {
         Thread.Sleep(1);
         System.Windows.Forms.Application.DoEvents();
    }
}

* См. https://blog.codinghorror.com/is-doevents-evil/ для более подробного обсуждения возможных ловушек использования Application.DoEvents().

Ответ 5

Если вы не хотите блокировать вещи, а также не хотите использовать многопоточность, вот решение для вас: https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx

Пользовательский интерфейс не блокируется, и таймер ждет 2 секунды, прежде чем что-то делать.

Вот код, следующий по ссылке:

        // Create a timer with a two second interval.
    aTimer = new System.Timers.Timer(2000);
    // Hook up the Elapsed event for the timer. 
    aTimer.Elapsed += OnTimedEvent;
    aTimer.Enabled = true;

    Console.WriteLine("Press the Enter key to exit the program... ");
    Console.ReadLine();
    Console.WriteLine("Terminating the application...");

Ответ 6

Я действительно вам не рекомендую использовать Thread.Sleep(2000) из-за нескольких причин (некоторые из них описаны здесь), но больше всего потому, что это не полезно, когда оно приходит к отладке/тестированию.

Я рекомендую использовать С# Timer вместо Thread.Sleep(). Таймеры позволяют часто выполнять методы (при необходимости) И очень легко использовать при тестировании! Там очень хороший пример того, как использовать таймер прямо за гиперссылкой - просто поместите свою логику "что произойдет через 2 секунды" прямо в метод Timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);.

Ответ 7

Посмотрите на класс System.Threading.Timer. Я думаю, это то, что вы ищете.

Пример кода в MSDN, похоже, показывает, что этот класс очень похож на то, что вы пытаетесь сделать (проверьте статус через определенное время).