views:

194

answers:

6

Hi everybody! I need to do a sort of "timeout" or pause in my method for 10 seconds (10000 milliseconds), but I'm not sure if the following would work as i do not have multi-threading.

Thread.Sleep(10000);

I will try to use that current code, but I would appreciate if someone could explain the best and correct way of doing this, especially if the above code does not work properly. Thanks!

UPDATE: This program is actually a console application that in the function in question is doing many HTTPWebRequests to one server, so I wish to delay them for a specified amount of milliseconds. Thus, no callback is required - all that is needed is an "unconditional pause" - basically just the whole thing stops for 10 seconds and then keeps going. I'm pleased that C# still considers this as a thread, so Thread.Sleep(...) would work. Thanks everybody!

+8  A: 

You may not have multi-threading, but you're still executing within a thread: all code executes in a thread.

Calling Thread.Sleep will indeed pause the current thread. Do you really want it to unconditionally pause for 10 seconds, or do you want to be able to be "woken up" by something else happening? If you're only actually using one thread, calling Sleep may well be the best way forward, but it will depend on the situation.

In particular, if you're writing a GUI app you don't want to use Thread.Sleep from the UI thread, as otherwise your whole app will become unresponsive for 10 seconds.

If you could give more information about your application, that would help us to advise you better.

Jon Skeet
My app is actually a console app that is making a huge amount of HTTP requests to one server so i don't want to overwhelm it and pause between batches of 4 or so that already pause automatically, but without such code. Yes I was hoping that C# still recognizes this as a thread so thank you!
Maxim Zaslavsky
+1  A: 

Yes, that works just fine.

You don't have to have multiple threads to make use of some of the methods in the Thread class. You always have at least one thread.

Guffa
+3  A: 

That will indeed pause the executing thread/method for 10 seconds. Are you seeing a specific problem?

Note that you shouldn't Sleep the UI thread - it would be better to do a callback instead.

Note also that there are other ways of blocking a thread that allow simpler access to get it going again (if you find it is OK after 2s); such as Monitor.Wait(obj, 10000) (allowing another thread to Pulse if needed to wake it up):

static void Main() {
    object lockObj = new object();
    lock (lockObj) {
        new Thread(GetInput).Start(lockObj);
        Monitor.Wait(lockObj, 10000);
    }
    Console.WriteLine("Main exiting");
}
static void GetInput(object state) {
    Console.WriteLine("press return...");
    string s = Console.ReadLine();
    lock (state) {
        Monitor.Pulse(state);
    }
    Console.WriteLine("GetInput exiting");
}

You can do this with Thread.Interrupt too, but IMO that is messier.

Marc Gravell
Thank you for the tips!
Maxim Zaslavsky
A: 

For a timeout, you should have a static volatile boolean isRunning class field. When the new thread starts, the isRunning must become true, and at the end must become false.

The main thread should have a method that loops for the isRunning during the timeout you define. When the timeout ends, you should implement the logic. But, never use the abort thread method.

A pause... there isn't a straightforward solution. It depends on what you are doing inside the thread. However, you could look at Monitor.Wait.

Ricardo
+1  A: 

Thread.Sleep is fine, and AFAIK the proper way. Even if you are not Multithreaded: There is always at least one Thread, and if you send that to sleep, it sleeps.

Another (bad) way is a spinlock, something like:

// Do never ever use this
private void DoNothing(){ }

private void KillCPU()
{
    DateTime target = DateTime.Now.AddSeconds(10);
    while(DateTime.Now < target) DoNothing();
    DoStuffAfterWaiting10Seconds();
}

This is sadly still being used by people and while it will halt your program for 10 seconds, it will run at 100% CPU Utilization (Well, on Multi-Core systems it's one core).

Michael Stum
Im laffing at that CPU hogging example - will need to put that down in my book as a classic way of filling up someone's CPU! :D thanks for the tip tho!
Maxim Zaslavsky
`while(DateTime.Now < target) { }` would do the trick also :)
Groo
Thankfully I'm only noobish in the terms of threading and all that good stuff - { } i understand tho. :D
Maxim Zaslavsky
Don't laugh - people still use that :/ (Okay, there are cases where a spinlock is appropriate, but that's like 0.0001% of all cases). Yes, I wasn't sure about the rules for "empty" loops, so I've added a dummy function just to be sure :)
Michael Stum
+1  A: 

You could use a separate thread to do it:

   ThreadPool.QueueUserWorkItem(
       delegate(object state)
       {
           Thread.Sleep(1000);
           Console.WriteLine("done");
       });

But, if this is a Windows Forms app, you will need to invoke the code after the delay from the Gui thread (this article, for example: http://stackoverflow.com/questions/661561/how-to-update-gui-from-another-thread-in-c).

[Edit] Just saw your update. If it's a console app, then this will work. But if you haven't used multiple threads so far, then you need to be aware that this code will be executed in a different thread, which means you will have to take care about thread synchronization issues.

If you don't need background workers, stick to "keeping it simple".

Groo