短时间使用 Thread.Sleep 的问题

发布于 2024-12-26 18:42:13 字数 555 浏览 1 评论 0原文

我有一个有 2 个线程的应用程序(现在),但似乎函数 Thread.Sleep() 工作得不太好。它会休眠线程,但需要更多时间(例如,我想让它休眠 5 毫秒,而它休眠 0.3 秒或更长时间)。这是代码:

int vlakien = 2;
Thread[] vlakna; 
vlakna = new Thread[vlakien];

for (int i = 0; i < vlakien; i++) 
{ try { vlakna[i] = new Thread(new ThreadStart(utok)); vlakna[i].Start(); } }

private void utok()
{
  //some code
  Thread.Sleep(5);
  //some code
}

我还尝试在函数 utok 中使用秒表使其睡眠,并且还需要更多时间:

Stopwatch SW = new Stopwatch(); SW.Start();
while(SW.ElapsedMilliseconds < 5000) ;

请帮忙。

I have an app with 2 threads (now), but it seems that function Thread.Sleep() doesn't work very good. It sleeps threads but it takes much more time (for example- I want to sleep it for 5ms and it sleeps for 0,3s or more). Here is code:

int vlakien = 2;
Thread[] vlakna; 
vlakna = new Thread[vlakien];

for (int i = 0; i < vlakien; i++) 
{ try { vlakna[i] = new Thread(new ThreadStart(utok)); vlakna[i].Start(); } }

private void utok()
{
  //some code
  Thread.Sleep(5);
  //some code
}

Also I tried to sleep it with Stopwatch in the function utok and it also takes more time:

Stopwatch SW = new Stopwatch(); SW.Start();
while(SW.ElapsedMilliseconds < 5000) ;

Please help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

终遇你 2025-01-02 18:42:14

它受系统时钟分辨率的影响。大约为 15 毫秒...您不能低于系统时钟的分辨率。看一下 链接(它是 C++,但你会明白关于计时器分辨率)。

It is affected by resolution of the system clock. It is around 15ms...you cannot go below resolution of the system clock. Take a look at this link (it is C++ but you will get idea about timer resolutions).

各自安好 2025-01-02 18:42:13

15ms 是 Windows 上的线程时间片(您实际上可以弄乱 Windows 并更改它......根本不推荐)。事情可能会提前耗尽他们的时间片,但任何事情都可能占用他们的全部时间片。

所以真的很难得到比这更好的了,事实上,实际上 20 或 30 毫秒更有可能。我曾经做过实时处理,其硬实时时间限制为 50 毫秒。如果您遵守某些规则,那么在 Windows 上效果很好(这是在 C++ 中)

15ms is the thread time slice on windows ( you can actually mess with windows and change that.... not at all recommended). Things can give their time slices up early, but anything could take their full time slice.

So its really hard to get any better than that, in fact, realistically 20 or 30 ms is more likely. I used to do real time processing which had a hard real time limit of 50ms. That worked well on windows if you obeyed certain rules ( it was in C++)

晚雾 2025-01-02 18:42:13

正如其他人所指出的,睡眠的默认分辨率是 10 或 15 毫秒,具体取决于 Windows 版本。

但是,您可以通过发出命令重新编程计时器以使用 1 毫秒分辨率。

timeBeginPeriod(1);
timeEndPeriod(1);

我们在串行通信服务中执行此操作

[DllImport(WINMM)]
internal static extern uint timeBeginPeriod(uint period);   

,其中能够准确地及时间隔发送非常重要。有些人不愿意这样做,因为这会导致 Windows 更频繁地执行其他基于计时器的操作。事实上,这并没有给我们带来明显的问题,而且我们有数百个安装,每个安装有数百个连接的串行设备。

As others have indicated, the default resolution of Sleep is 10 or 15 milliseconds, depending on the edition of Windows.

However, you can reprogram the timer to use a 1 millisecond resolution by issuing a

timeBeginPeriod(1);
timeEndPeriod(1);

where

[DllImport(WINMM)]
internal static extern uint timeBeginPeriod(uint period);   

We do this in our serial communications services where being able to accurately space out sends in time is important. Some people are reluctant to do this because it causes Windows to do other things that are based off of the timer more frequently as well. In reality this has caused no discernible issues for us, and we have hundreds of installs each with hundreds of serial devices connected.

ぇ气 2025-01-02 18:42:13

Microsoft C# 中的睡眠保证了最短的时间。它睡眠时间少于5毫秒绝对是一个问题。另外,秒表的测量可能不是很精确,请尝试高精度媒体计时器。

Sleep in Microsoft C# guarantees a minimum amount of time. It sleeping less than 5 milliseconds is definitely a problem. Also Stopwatch may not be very precise measurement, try the high precision media timers.

书间行客 2025-01-02 18:42:13

传递给 Thread.Sleep 的参数是睡眠的最短时间,而不是确切的时间。

The parameter passed into Thread.Sleep is a minimum time to sleep, not an exact time.

本王不退位尔等都是臣 2025-01-02 18:42:13

这是一个平台相关等待,您可以在任何项目中使用,该项目通过将线程挂起指定的时间来工作,并使用您可以实现的最低可能分辨率。系统,这可能是 1ms

它不会比正常的 Thread.Sleep 使用更多的 CPU

/*
*MIT License
*
*Copyright (c) 2023 S Christison
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/

using System.Runtime.InteropServices;

namespace System.Threading
{
    /// <summary>
    /// Platform Dependent Wait
    /// Accurately wait down to 1ms if your platform will allow it
    /// Wont murder your CPU
    public static class Delay
    {
        internal const string windowsMultimediaAPIString = "winmm.dll";

        [DllImport(windowsMultimediaAPIString)]
        internal static extern int timeBeginPeriod(int period);

        [DllImport(windowsMultimediaAPIString)]
        internal static extern int timeEndPeriod(int period);

        [DllImport(windowsMultimediaAPIString)]
        internal static extern int timeGetDevCaps(ref TimerCapabilities caps, int sizeOfTimerCaps);

        internal static TimerCapabilities Capabilities;

        static Delay()
        {
            timeGetDevCaps(ref Capabilities, Marshal.SizeOf(Capabilities));
        }

        /// <summary>
        /// Platform Dependent Wait
        /// Accurately wait down to 1ms if your platform will allow it
        /// Wont murder your CPU
        /// </summary>
        /// <param name="delayMs"></param>
        public static void Wait(int delayMs)
        {
            timeBeginPeriod(Capabilities.PeriodMinimum);
            Thread.Sleep(delayMs);
            timeEndPeriod(Capabilities.PeriodMinimum);
        }

        /// <summary>
        /// The Min/Max supported period for the Mutlimedia Timer in milliseconds
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct TimerCapabilities
        {
            /// <summary>Minimum supported period in milliseconds.</summary>
            public int PeriodMinimum;

            /// <summary>Maximum supported period in milliseconds.</summary>
            public int PeriodMaximum;
        }
    }
}

在此处输入图像描述

这适用于任何版本的 。 NET,如果您的平台不支持此功能,那么它与普通的 Thread.Sleep 相同

This is a Platform Dependent Wait you can use in any project that works by suspending the Thread for the amount of time you specify with the lowest possible resolution that can be achieved by your system, which will likely be 1ms

It won't use more CPU than a normal Thread.Sleep

/*
*MIT License
*
*Copyright (c) 2023 S Christison
*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the "Software"), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in all
*copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*SOFTWARE.
*/

using System.Runtime.InteropServices;

namespace System.Threading
{
    /// <summary>
    /// Platform Dependent Wait
    /// Accurately wait down to 1ms if your platform will allow it
    /// Wont murder your CPU
    public static class Delay
    {
        internal const string windowsMultimediaAPIString = "winmm.dll";

        [DllImport(windowsMultimediaAPIString)]
        internal static extern int timeBeginPeriod(int period);

        [DllImport(windowsMultimediaAPIString)]
        internal static extern int timeEndPeriod(int period);

        [DllImport(windowsMultimediaAPIString)]
        internal static extern int timeGetDevCaps(ref TimerCapabilities caps, int sizeOfTimerCaps);

        internal static TimerCapabilities Capabilities;

        static Delay()
        {
            timeGetDevCaps(ref Capabilities, Marshal.SizeOf(Capabilities));
        }

        /// <summary>
        /// Platform Dependent Wait
        /// Accurately wait down to 1ms if your platform will allow it
        /// Wont murder your CPU
        /// </summary>
        /// <param name="delayMs"></param>
        public static void Wait(int delayMs)
        {
            timeBeginPeriod(Capabilities.PeriodMinimum);
            Thread.Sleep(delayMs);
            timeEndPeriod(Capabilities.PeriodMinimum);
        }

        /// <summary>
        /// The Min/Max supported period for the Mutlimedia Timer in milliseconds
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct TimerCapabilities
        {
            /// <summary>Minimum supported period in milliseconds.</summary>
            public int PeriodMinimum;

            /// <summary>Maximum supported period in milliseconds.</summary>
            public int PeriodMaximum;
        }
    }
}

enter image description here

This will work with any version of .NET and if your platform doesn't support this then it is the same as a normal Thread.Sleep

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文