2

Can I do something like that in order to wait, for example 5 seconds, before continue with other method and without freeze my UI ?

System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    System.Threading.Thread.Sleep(5000);
    // Code to do some method
});
Tomas Walek
  • 2,516
  • 2
  • 23
  • 37
user2214609
  • 4,713
  • 9
  • 34
  • 41

2 Answers2

10

You should use:

await Task.Delay(5000);
Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
  • In fact, IIRC, this is the recommended way of delaying a running task. – Simon Whitehead Oct 16 '13 at 09:34
  • The only difference is that the code after the `Task.Delay()` is executed on the current dispatcher instead of the `Factory.StartNew` `ThreadPool` thread. – Jeroen van Langen Oct 16 '13 at 09:38
  • 1
    And if OP is not targeting .NET 4.5? – Ondrej Janacek Oct 16 '13 at 09:41
  • @OndrejJanacek: He could spawn a thread, `Thread.Sleep()` on it and invoke a delegate on the `Dispatcher` to Continue execution without blocking the UI. – Jeroen van Langen Oct 16 '13 at 09:43
  • @OndrejJanacek In that case he should have put the appropriate .Net tag in his question; otherwise, the default is to assume that they are using a version that's not more than a year old. Or he could use [Async for .Net 4](http://www.nuget.org/packages/Microsoft.Bcl.Async) – Matthew Watson Oct 16 '13 at 09:44
  • 1
    @MatthewWatson I was not aware of such a convention here on SO. – Ondrej Janacek Oct 16 '13 at 09:46
  • Also a big difference is that the `Task.Delay()` will use a `Timer` instead of blocking a thread for waiting. – Jeroen van Langen Oct 16 '13 at 09:49
  • 1
    @OndrejJanacek I just meant that people tend to assume you're using the latest stuff unless otherwise stated - otherwise every answer would have to provide solutions for versions of .Net going back years. For example, people will tend to provide answers which require the use of Linq, even though that didn't exist in .Net 2. – Matthew Watson Oct 16 '13 at 09:57
  • @MatthewWatson Yeah, it gives a sense to me :) – Ondrej Janacek Oct 16 '13 at 10:00
1

Thread.Sleep() is not recommended. There is no good in blocking a thread/task for 5 seconds.

As mentioned in @Jeroen van Langen's answer, await Task.Delay() is the best way. However, if for some reason you are not able to use async/await mechanism, second best option will be to setup a one-time 5 second timer. Windows.Forms.Timer for WinForms or DispatcherTimer for WPF.

(Task.Delay() is in turn implemented by a timer.)

Community
  • 1
  • 1
YK1
  • 7,327
  • 1
  • 21
  • 28
  • What about using Task.Delay(5000).ContinueWith(x => MyMethod()) ?? and what is the meaning of await before Task.Delay() ? – user2214609 Oct 16 '13 at 10:27
  • Sure you can, but be careful, your delegate will not run on UI thread by default. You will have to pass the SynchronizationContextSchedueler to the `ContinueWith` method. See http://stackoverflow.com/a/4331287/1529246 – YK1 Oct 16 '13 at 10:30
  • To learn about `await` use your favorite search engine and search for `c# 5.0 async await`. It is new C# 5.0 feature - and it is non-blocking. `await` also captures current synchrinizationcontext automatically. – YK1 Oct 16 '13 at 10:34
  • This not compile: Task UITask = Task.Delay(5000).ContinueWith(() => { myMethod(); }, TaskScheduler.FromCurrentSynchronizationContext()); Delegate 'System.Action' does not take 0 argumen – user2214609 Oct 16 '13 at 10:45
  • change it to this `...ContinueWith( _ => { myMethod(); } ...` where the `_` represents the completed task of `Task.Delay()`. You generally wont use that variable so convention is to name it `_`. – YK1 Oct 16 '13 at 11:05