Замена 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.