Подождите n секунд, затем следующая строка кода без зависания формы

Привет, я пытаюсь найти способ ожидания в несколько миллисекунд, прежде чем перейти к следующей строке кода,

Я просмотрел Thread.Sleep, но это заморозит основную форму, я бы хотел, чтобы она оставалась активной.

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

Я не мог найти способ использовать task.delay или фонового работника в ожидании, которое я хотел.

Псевдокод:

Wait 2 - 6 seconds
Log "waiting"
Log "waiting"
Log "waiting"
Stop Waiting - Run next line of code.

Методы, которые я пробовал, просто замораживают форму и затем заполняют журнал, мне просто нужен простой метод ожидания без замораживания формы и без необходимости иметь дело с вызываемыми событиями, что означает, что следующая строка не запускается.

Любая помощь была бы потрясающей, потому что я все еще новичок в С#, и это меня немного бесило :(


person Sam    schedule 14.04.2013    source источник
comment
Это WinForms или WPF?   -  person outcoldman    schedule 14.04.2013
comment
Приложение формы Windows   -  person Sam    schedule 14.04.2013


Ответы (3)


Ключевое слово await в сочетании с Task.Delay делает это тривиальным.

public async Task Foo()
{
    await Task.Delay(2000);
    txtConsole.AppendText("Waiting...");
    DoStuff();
}
person Servy    schedule 14.04.2013
comment
Спасибо, это все, что мне было нужно, я пробовал Task.Delay, но я не знал, что его нужно использовать в сочетании с асинхронной задачей и ожиданием. - person Sam; 14.04.2013
comment
@Sam Ты, конечно, не должен этого делать. Вместо этого вы можете использовать Task.Delay(2000).ContinueWith(t=>DoStuff(), ..., Task.Factory.FromCurrentSynchronizationContext());, что в конечном итоге приведет к рефакторингу await. - person Servy; 14.04.2013
comment
@Servy, как бы вы поступили в .Net4.0? - person Arvo Bowen; 26.04.2016
comment
@ArvoBowen Вы бы использовали ContinueWith вместо await. Если вам нужна хорошая семантика обработки ошибок, это немного больше работы, но помимо обработки ошибок вы просто поместите остальную часть кода в продолжение, и это будет не так уж плохо. - person Servy; 26.04.2016
comment
@Servy, так что, думаю, для меня это будет Task.Factory.StartNew(() => DoStuffStart(), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).ContinueWith((t) => DoStuffFinished(t.Result));. ;) - person Arvo Bowen; 26.04.2016
comment
Task.Delay() может вызвать проблемы с параллелизмом, поскольку он приводит к выполнению. - person ; 13.08.2018
comment
@IamDOM Весь код выполняется в потоке пользовательского интерфейса, поэтому ничего не выполняется одновременно. Да, между вызовами DoStuff могут выполняться другие события пользовательского интерфейса. Это нужно будет написать, чтобы поддержать это. Я не вижу в вопросе указаний на то, что это не так. Альтернатив действительно нет. - person Servy; 13.08.2018
comment
Я забыл взять вопрос в контексте. Виноват. - person ; 13.08.2018

Попробуйте использовать DispatcherTimer. Это довольно удобный объект, который выполняет всю работу по делегированию UI-потоку.

Например:

private DispatcherTimer _dtTimer = null;

public Constructor1(){
  _dtTimer = new DispatcherTimer();
  _dtTimer.Tick += new System.EventHandler(HandleTick);
  _dtTimer.Interval = new TimeSpan(0, 0, 0, 2); //Timespan of 2 seconds
  _dtTimer.Start();
}

private void HandleTick(object sender, System.EventArgs e) {
  _uiTextBlock.Text = "Timer ticked!";
}
person Daniel    schedule 14.04.2013

В этом случае таймер должен работать нормально, если вы не поместите Thread.Sleep в его обработчик или сам обработчик не займет слишком много времени для завершения.

Вы не указали используемую платформу пользовательского интерфейса или версию .Net, но для последней версии .Net вы можете использовать async/await. Таким образом, пользовательский интерфейс не будет зависать, пока ваш код ожидает выполнения фоновой задачи.

void async MyMethod()
{  
    var result = await Task.Run(() => long_running_code);
}
person alex    schedule 14.04.2013