Why is Thread.Sleep so harmful

前端 未结 8 2025
天涯浪人
天涯浪人 2020-11-22 06:30

I often see it mentioned that Thread.Sleep(); should not be used, but I can\'t understand why this is so. If Thread.Sleep(); can cause trouble, are

相关标签:
8条回答
  • 2020-11-22 06:34

    It is the 1).spinning and 2).polling loop of your examples that people caution against, not the Thread.Sleep() part. I think Thread.Sleep() is usually added to easily improve code that is spinning or in a polling loop, so it is just associated with "bad" code.

    In addition people do stuff like:

    while(inWait)Thread.Sleep(5000); 
    

    where the variable inWait is not accessed in a thread-safe manner, which also causes problems.

    What programmers want to see is the threads controlled by Events and Signaling and Locking constructs, and when you do that you won't have need for Thread.Sleep(), and the concerns about thread-safe variable access are also eliminated. As an example, could you create an event handler associated with the FileSystemWatcher class and use an event to trigger your 2nd example instead of looping?

    As Andreas N. mentioned, read Threading in C#, by Joe Albahari, it is really really good.

    0 讨论(0)
  • 2020-11-22 06:36

    SCENARIO 1 - wait for async task completion: I agree that WaitHandle/Auto|ManualResetEvent should be used in scenario where a thread is waiting for task on another thread to complete.

    SCENARIO 2 - timing while loop: However, as a crude timing mechanism (while+Thread.Sleep) is perfectly fine for 99% of applications which does NOT require knowing exactly when the blocked Thread should "wake up*. The argument that it takes 200k cycles to create the thread is also invalid - the timing loop thread needs be created anyway and 200k cycles is just another big number (tell me how many cycles to open a file/socket/db calls?).

    So if while+Thread.Sleep works, why complicate things? Only syntax lawyers would, be practical!

    0 讨论(0)
  • 2020-11-22 06:40

    I have a use case that I don't quite see covered here, and will argue that this is a valid reason to use Thread.Sleep():

    In a console application running cleanup jobs, I need to make a large amount of fairly expensive database calls, to a DB shared by thousands of concurrent users. In order to not hammer the DB and exclude others for hours, I'll need a pause between calls, in the order of 100 ms. This is not related to timing, just to yielding access to the DB for other threads.

    Spending 2000-8000 cycles on context switching between calls that may take 500 ms to execute is benign, as does having 1 MB of stack for the thread, which runs as a single instance on a server.

    0 讨论(0)
  • 2020-11-22 06:47

    Sleep is used in cases where independent program(s) that you have no control over may sometimes use a commonly used resource (say, a file), that your program needs to access when it runs, and when the resource is in use by these other programs your program is blocked from using it. In this case, where you access the resource in your code, you put your access of the resource in a try-catch (to catch the exception when you can't access the resource), and you put this in a while loop. If the resource is free, the sleep never gets called. But if the resource is blocked, then you sleep for an appropriate amount of time, and attempt to access the resource again (this why you're looping). However, bear in mind that you must put some kind of limiter on the loop, so it's not a potentially infinite loop. You can set your limiting condition to be N number of attempts (this is what I usually use), or check the system clock, add a fixed amount of time to get a time limit, and quit attempting access if you hit the time limit.

    0 讨论(0)
  • 2020-11-22 06:49

    I agree with many here, but I also think it depends.

    Recently I did this code:

    private void animate(FlowLayoutPanel element, int start, int end)
    {
        bool asc = end > start;
        element.Show();
        while (start != end) {
            start += asc ? 1 : -1;
            element.Height = start;
            Thread.Sleep(1);
        }
        if (!asc)
        {
            element.Hide();
        }
        element.Focus();
    }
    

    It was a simple animate-function, and I used Thread.Sleep on it.

    My conclusion, if it does the job, use it.

    0 讨论(0)
  • 2020-11-22 06:50

    I would like to answer this question from a coding-politics perspective, which may or may not be helpful to anyone. But particularly when you're dealing with tools that are intended for 9-5 corporate programmers, people who write documentation tend to use words like "should not" and "never" to mean "don't do this unless you really know what you're doing and why".

    A couple of my other favorites in the C# world are that they tell you to "never call lock(this)" or "never call GC.Collect()". These two are forcefully declared in many blogs and official documentation, and IMO are complete misinformation. On some level this misinformation serves its purpose, in that it keeps the beginners away from doing things they don't understand before fully researching the alternatives, but at the same time, it makes it difficult to find REAL information via search-engines that all seem to point to articles telling you not to do something while offering no answer to the question "why not?"

    Politically, it boils down to what people consider "good design" or "bad design". Official documentation should not be dictating the design of my application. If there's truly a technical reason that you shouldn't call sleep(), then IMO the documentation should state that it is totally okay to call it under specific scenarios, but maybe offer some alternative solutions that are scenario independent or more appropriate for the other scenarios.

    Clearly calling "sleep()" is useful in many situations when deadlines are clearly defined in real-world-time terms, however, there are more sophisticated systems for waiting on and signalling threads that should be considered and understood before you start throwing sleep() into your code, and throwing unnecessary sleep() statements in your code is generally considered a beginners' tactic.

    0 讨论(0)
提交回复
热议问题