37

I want to put a delay between 2 operations without keeping busy the thread

 workA();
 Thread.Sleep(1000);
 workB();

The thread must exit after workA and execute workB (maybe in a new thread) after some delay.

I wonder if it's possible some equevalent of this pseudocode

workA();
Thread.BeginSleep(1000, workB); // callback

edit My program is in .NET 2.0

edit 2 : System.Timers.Timer.Elapsed event will raise the event after 1000 ms. I dont know if the timer thread will be busy for 1000 ms. (so I dont gain thread economy)

albert
  • 1,493
  • 1
  • 15
  • 33
  • Don't understand. Your Thread.Sleep() call will put a delay between 2 operations without keeping busy the thread. Do I misunderstand what you want? – Martin James Apr 10 '13 at 12:18
  • Yes but the Threadpool for this period of time (1000 ms) will have 1 less thread available. – albert Apr 10 '13 at 12:32
  • 1
    You might prefer `System.Threading.Timer` for this - not `System.Timers.Timer` and no - there is no "timer thread" - the wait is controlled in the OS kernel – Nick Butler Apr 10 '13 at 13:16
  • [`MSDN: Comparing the Timer Classes`](http://msdn.microsoft.com/en-us/magazine/cc164015.aspx) - `System.Timers.Timer` is useful if you have a `SynchronizationContext` involved. – Nick Butler Apr 10 '13 at 13:18
  • Thank you Nicholas for the clarification – albert Apr 10 '13 at 13:40

1 Answers1

67

Do you mean:

Task.Delay(1000).ContinueWith(t => workB());

Alternatively, create a Timer manually.

Note this looks prettier in async code:

async Task Foo() {
    workA();
    await Task.Delay(1000);
    workB();
}

edit: with your .NET 2.0 update, you would have to setup your own Timer with callback. There is a nuget package System.Threading.Tasks that brings the Task API down to .NET 3.5, but a: it doesn't go to 2.0, and b: I don't think it includes Task.Delay.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • or even `Task.Delay(1000).Wait();` if you don't want an async func. – Josh Mc Jan 03 '17 at 22:37
  • 7
    @Josh you just made me cry a little. Please don't ever do that. If you're lucky it'll just be horribly inefficient. If you're unlucky: you just deadlocked a thread. It all depends on the sync context. If you want to wait synchronously: `Thread.Sleep(1000)` – Marc Gravell Jan 04 '17 at 00:50
  • 3
    thanks for the reply, I don't suppose you have anywhere I could go read more about this (the why I mean)? (especially the deadlock the thread part) – Josh Mc Jan 04 '17 at 01:46
  • 4
    For anyone interested in future `.Wait()` is actually blocking, so defeats the purpose of your asynchronous call entirely, and Marcs reasoning makes sense to me now. – Josh Mc Jan 05 '17 at 21:04