Замена Thread.Sleep в .NET для Магазина Windows

98

Thread.Sleep , похоже, не поддерживается в .NET для приложений Магазина Windows.

Например, это

System.Threading.Thread.Sleep(1000);

будет компилироваться при нацеливании на любую .NET Framework (2.0, 3.5, 4.0, 4.5), но не при нацеливании на .NET для приложений Магазина Windows (или в переносимой библиотеке классов, ориентированной как на 4.5, так и на хранилище).

System.Threading.Thread все еще существует, просто у него нет метода Sleep.

Мне нужно отложить что-то на несколько секунд в моем приложении, есть ли подходящая замена?

ИЗМЕНИТЬ, почему необходима задержка: Мое приложение - это игра, и задержка должна создать впечатление, будто компьютерный противник «думает» о своем следующем шаге. Метод уже вызван асинхронно (основной поток не заблокирован), я просто хочу уменьшить время отклика.

Макс
источник
2
Учитывая, что приложения Магазина Windows не должны иметь возможность замораживать пользовательский интерфейс (все должно быть асинхронным), имеет смысл, что он не поддерживается.
Sruly
2
У вас есть События или Monitorкласс? Вы можете использовать Waitметод с таймаутом для имитации сна.
Tudor
это для Apptivate.ms? : 3
EaterOfCode
3
Ура за то, что выбросили Thread.Sleepна помойку плохих технологий.
Спендер

Ответы:

203

Приложения Магазина Windows поддерживают асинхронность - и «асинхронная пауза» обеспечивается Task.Delay. Итак, внутри асинхронного метода вы должны написать:

await Task.Delay(TimeSpan.FromSeconds(30));

... или как хотите отсрочку. Асинхронный метод будет продолжен через 30 секунд, но поток не будет заблокирован, как и для всех awaitвыражений.

Джон Скит
источник
1
К сожалению, Task.Delay не поддерживается при нацеливании на .NET 4.5 + store + WP7 в переносимой библиотеке классов. Думаю, мне придется переместить это в классы, специфичные для платформы.
Макс
1
@Max: Нет, потому что он не существовал до .NET 4.5. IIRC, сам WP7 не поддерживает TPL. (Я могу ошибаться ...)
Джон Скит
4
При необходимости можно прибить .RunSynchronously().
HappyNomad
1
@RAM: Ну Thread.Sleep это поддерживается в .NET 3.5, так что вопрос не относится. Не сомневаюсь , что у вас есть на вопрос, но это не звучит , как будто это так же , как этот. Пожалуйста, прочтите tinyurl.com/stack-hints и задайте новый вопрос.
Джон Скит,
2
@RAM: Я не уверен, как я должен был догадаться об этом из ваших комментариев. На SO уже есть много похожих вопросов о WPF и анимации.
Джон Скит
46

Ненавижу утверждать очевидное, но на случай, если кто-то захочет одну строчку System.Threading.Tasks.Task.Delay(3000).Wait()

Энтони Томас
источник
20

У меня была такая же проблема, и я нашел другое интересное решение, которым хотел с вами поделиться. Если вы действительно хотите заблокировать поток, я бы сделал это так (спасибо @Brannon за "тонкий" намек):

// `waitHandle.Set` is never called, so we wait always until the timeout occurs
using (var waitHandle = new ManualResetEventSlim(initialState: false))
{
    waitHandle.Wait(TimeSpan.FromSeconds(5));
}
Йоханнес Эггер
источник
Это лучший ответ для переносимого кодирования.
zezba9000
Используйте "тонкую" версию этого.
Brannon
11

MainPage.xaml.cs

public MainPage()
{
  this.InitializeComponent();
  this.WaitForFiveSeconds();
}

private async void WaitForFiveSeconds()
{
  await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(5));
  // do something after 5 seconds!
}
Бенни Нойгебауэр
источник
-7

Практически НЕТ причин (кроме тестовых целей) для использования ВСЕГДА Thread.Sleep().

ЕСЛИ (и только если) у вас есть очень веская причина для отправки потока в спящий режим, вы можете захотеть проверить Task.Delay(), что вы можете ждать, чтобы «подождать» в течение определенного времени. Хотя никогда не стоит оставлять нить без дела и ничего не делать. Плохая практика ...

игримпе
источник
9
Я не согласен. Если поток является фоновым потоком и период сна короткий, то более эффективно, если он будет спать на несколько миллисекунд, чем использование таймера.
Джейсон Стил,
1
и иногда вам говорят сделать это, несмотря на то, что вы сообщили упомянутому авторитету о последствиях;)
Jordan