Thread.Sleep replacement in .NET for Windows Store
Asked Answered
K

5

99

Thread.Sleep doesn't seem to be supported in .NET for Windows Store apps.

For example, this

System.Threading.Thread.Sleep(1000);

will compile when targeting any .NET Framework (2.0, 3.5, 4.0, 4.5), but not when targeting .NET for Windows Store apps (or in a portable class library which targets both 4.5 and store).

System.Threading.Thread is still there, it just doesn't have the Sleep method.

I need to delay something for a few seconds in my app, is there a suitable replacement?

EDIT why the delay is needed: My app is a game and the delay is to make it look like the computer opponent is "thinking" about his next move. The method is already called asynchronously (main thread isn't blocked), I just want to slow the response time down.

Kibitka answered 28/9, 2012 at 13:44 Comment(4)
Considering Windows Store apps are not supposed to be able to freeze the UI (everything is supposed to be async) it makes sense that it is not supported.Curry
Do you have Events or the Monitor class? You can use the Wait method with a timeout to simulate a sleep.Shuma
is this for Apptivate.ms ? :3Athene
Yay for banishing Thread.Sleep to the dustbin of bad tech.Justify
G
203

Windows Store apps embrace asynchrony - and an "asynchronous pause" is provided by Task.Delay. So within an asynchronous method, you'd write:

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

... or whatever delay you want. The asynchronous method will continue 30 seconds later, but the thread will not be blocked, just as for all await expressions.

Gandhi answered 28/9, 2012 at 13:48 Comment(10)
Unfortunately, Task.Delay doesn't seem to be supported when targeting .NET 4.5 + store + WP7 in a portable class library.. I guess I'll have move this into the platform specific classes.Kibitka
@Max: No, because it didn't exist before .NET 4.5. IIRC, WP7 itself doesn't have any TPL support. (I could be wrong...)Gandhi
You can tack on .RunSynchronously() if needed.Abecedarian
You can also use Microsoft.Bcl.Async's TaskEx.Delay, you cab grab the package using NuGet.Endways
If it's awaitable, why didn't they call it DelayAsync()?Poulos
@Jay: It's felt that methods which are clearly about asynchrony are okay without the suffix, e.g. Task.Run.Gandhi
@RAM: Well then it's not a Windows Store app to start with, so we're in a completely different context - I'd suggest that in that case you ask a new question with more details.Gandhi
@JonSkeet, my platform is C# .NET 3.5 WPF. i found some ways but i don't know what is the best and short way. do you know any good answer in stackoverflow for it? I can write a new question but i like know your suggestions. do you suggest new question in stackoverflow? thanks...Laniary
@RAM: Well Thread.Sleep is supported in .NET 3.5, so the question doesn't apply. No doubt you have a question, but it doesn't sound like it's the same as this one. Please read tinyurl.com/stack-hints then ask a new question.Gandhi
@RAM: I'm not sure how I was meant to guess that from your comments. There are plenty of similar questions on SO already about WPF and animation.Gandhi
D
46

Hate to state the obvious but in case anybody wanted a single line System.Threading.Tasks.Task.Delay(3000).Wait()

Declinate answered 3/11, 2014 at 19:23 Comment(0)
J
20

I just had the same problem and found another interesting solution that I wanted to share with you. If you really want to block the thread I would do it like this (thanks @Brannon for the "slim" hint):

// `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));
}
Jackhammer answered 4/5, 2013 at 12:29 Comment(2)
This is the best answer for portable coding.Pedantry
Use the "slim" version of this.Villous
C
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!
}
Clarion answered 8/10, 2012 at 20:41 Comment(0)
C
-7

There is almost NO reason (except for testing purposes) to EVER use Thread.Sleep().

IF (and only if) you have a very good reason to send a thread to sleep, you might want to check Task.Delay() , which you can await to "wait" for a specified time. Though it's never a good idea to have a thread sitting around and do nothing. Bad practise ...

Coparcener answered 28/9, 2012 at 13:48 Comment(2)
I disagree. If the thread is a background thread and the sleep is short then it is more efficient to have it sleep for a few milliseconds than using a timer.Entrails
and sometimes you're told to do it despite advising said authority figure of the consequences ;)Leotie

© 2022 - 2024 — McMap. All rights reserved.