C# 线程的用途。睡眠(1)?

C# 线程的用途。睡眠(1)?,c#,multithreading,C#,Multithreading,我正在阅读一些线程基础知识,在msdn网站上我找到了这段代码 // Put the main thread to sleep for 1 millisecond to // allow the worker thread to do some work: Thread.Sleep(1); 以下是指向页面的链接: 为什么主线程的睡眠时间为1毫秒?如果主线程持续运行,次线程是否不会启动其任务?或者该示例是针对需要1毫秒才能完成的任务?如果任务通常需要5秒钟才能完成,那么主线

我正在阅读一些线程基础知识,在msdn网站上我找到了这段代码

    // Put the main thread to sleep for 1 millisecond to
    // allow the worker thread to do some work:
    Thread.Sleep(1);
以下是指向页面的链接:

为什么主线程的睡眠时间为1毫秒?如果主线程持续运行,次线程是否不会启动其任务?或者该示例是针对需要1毫秒才能完成的任务?如果任务通常需要5秒钟才能完成,那么主线程应该休眠5000毫秒吗

如果这仅仅是关于CPU的使用,这里有一个类似的例子

如有任何意见,将不胜感激


谢谢。

该代码中的
1
并不特别;它最终总是会睡得更长,因为事情并不是那么精确,放弃你的时间片并不等于你从操作系统得到它的任何保证

Thread.Sleep()
中的time参数的作用是,您的线程将至少在大致相同的时间内产生时间

因此,代码只是显式地放弃了它的时间段。一般来说,不需要这样的代码,因为操作系统将为您管理线程,抢先中断它们在其他线程上工作

这类代码通常用于“线程示例”,其中作者希望强制某些人为事件来证明某些竞争条件,或类似情况(在您的示例中似乎就是这种情况)


正如Jon Hanna在回答这个问题时所指出的那样,
Sleep(0)
Sleep(1)
(或任何其他非零数字)之间存在着微妙但重要的区别,正如ChrisF所暗示的,这在某些线程情况下可能很重要

这两者都涉及线程优先级;线程可以被赋予更高/更低的优先级,这样,只要有更高优先级的线程有工作要做,低优先级的线程就永远不会执行。在这种情况下,可能需要睡眠(1)。。。然而

低优先级线程也受同一系统上其他进程的影响;因此,虽然您的进程可能没有运行更高优先级的线程,但如果其他线程有,您的进程仍然不会运行


不过,这通常不是你需要担心的事情;默认优先级是“正常”优先级,在大多数情况下,您不应该更改它。提高或降低它有很多含义。

这只是为了示例,他们希望确保工作线程在主线程终止之前至少有机会打印一次“工作线程:工作…”


正如Andrew所暗示的,这在示例中很重要,特别是因为如果在单处理器机器上运行,主线程可能不会放弃处理器,在后台线程有机会迭代一次之前杀死它。

如果主线程根本不睡眠,那么其他线程将无法运行

插入任意长度的
睡眠
,允许其他线程有一定的处理时间。使用较小的值(在本例中为1毫秒)意味着主线程似乎没有锁定。您可以使用
Sleep(0)
,但正如Jon Hanna指出的那样,这与
Sleep(1)
(或者任何正值)有不同的含义,因为它只允许运行优先级相同的线程

如果任务耗时5秒,则主线程将睡眠5000毫秒,但时间会更长。

线程。如果优先级相同的线程准备好调度,则睡眠(0)
将放弃线程的剩余时间片

Thread.Sleep(1)
(或任何其他值,但1是具有此效果的最低值)将无条件放弃线程的其余时间片。如果它想确保即使是优先级较低的线程也有机会运行(这样的线程可能正在执行阻止该线程的操作,它必须这样做),那么它就是要去做的


有更多关于这方面的信息。

我今天注意到一件有趣的事情。中断线程会引发
ThreadInterruptedException
。我试图捕捉异常,但由于某种原因未能捕捉到。我的同事建议我在catch语句之前放置
Thread.Sleep(1)
,这样我就可以捕获
ThreadInterruptedException

        // Start the listener
        tcpListener_ = new TcpListener(ipAddress[0], int.Parse(portNumber_));
        tcpListener_.Start();
        try
        {
            // Wait for client connection
            while (true)
            {
                // Wait for the new connection from the client
                if (tcpListener_.Pending())
                {
                    socket_ = tcpListener_.AcceptSocket();
                    changeState(InstrumentState.Connected);

                    readSocket();
                }
                Thread.Sleep(1);
            }
        }

        catch (ThreadInterruptedException) { }

        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Contineo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            Console.WriteLine(ex.StackTrace);
        }
另一类

        if (instrumentThread_ != null)
        {
            instrumentThread_.Interrupt();
            instrumentThread_ = null;
        }

Joe Albahari在这里写了关于这个问题的文章:谢谢,这似乎是我在这个问题上需要的所有信息。那么这段代码实际上是在破坏线程的功能?因为其目的是一次执行多个任务,而不必等待对方完成。更好的做法是不使用它?@YahooMania不,在某些情况下这样做是至关重要的。@YahooMania但除了线程示例之外,您不一定会遇到这种情况。这段代码的存在是为了帮助说明一点。@AndrewBarber在线程示例和实际线程代码之外,这当然是阅读踏板示例的全部要点。当然,在这种情况下这是人为的,但是如果你等待一个依赖于另一个线程的条件太久了,那么不解释放弃切片的重要性,就违背了有人试图学习线程的目的。@AndrewBarber在底部附近看到我的答案。严格来说,这不是真的。最小值为0,但在这种情况下它不会让低优先级线程使用。如果您执行了
Pending()
测试,并在
启动之前让
AcceptSocket()
阻塞,它也可能被捕获。原因是我的回答的延伸。线程不会抛出
ThreadInterruptedException
,直到它阻塞或放弃它的时间片(不仅仅是到达其量程的末尾并返回等待下一个量程),这是
thread.Sleep(1)
导致的,但是
thread.Sleep(0)
不会。进入监视器或等待ev