Thread.Sleep заміна в .NET для Windows Store


98

Thread.Sleep не підтримується в .NET для додатків Windows Store.

Наприклад, це

System.Threading.Thread.Sleep(1000);

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

System.Threading.Thread все ще є, у нього просто немає способу сну.

Мені потрібно щось затримати на кілька секунд у моєму додатку, чи є відповідна заміна?

РЕДАКТУЙТЕ, чому потрібна затримка: мій додаток - це гра, і затримка полягає в тому, щоб він виглядав так, як опонент комп'ютера "думає" про свій наступний крок. Метод вже називається асинхронним (основний потік не заблокований), я просто хочу сповільнити час реакції.


2
Зважаючи на те, що програми Windows Store не мають змоги заморозити інтерфейс користувача (усе має бути асинхронізованим), має сенс, що він не підтримується.
Sruly

2
У вас є події чи Monitorклас? WaitДля імітації сну можна використовувати метод з таймаутом.
Тудор

це для Apptivate.ms? : 3
EaterOfCode

3
Так, за прогон Thread.Sleepна смітник поганих технологій.
витрачається

Відповіді:


203

Програми Windows Store охоплюють асинхронність - і "асинхронна пауза" надає компанія 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

Використовуйте "тонкий" варіант цього.
Браннон

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.