.net 使用线程时出现问题,请短时间休眠

h9vpoimq  于 2023-02-10  发布在  .NET
关注(0)|答案(6)|浏览(236)

我有一个有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) ;

请帮帮我。

58wvjzkj

58wvjzkj1#

15ms是windows上的线程时间片(你实际上可以乱搞windows并改变它...一点也不推荐)。东西可以很早就给予它们的时间片,但任何东西都可能占用它们的全部时间片。
所以很难找到比这更好的,实际上,20或30毫秒更有可能。我曾经做过实时处理,它有一个50毫秒的严格实时限制。如果你遵守某些规则,这在Windows上工作得很好(在C++中)

ssgvzors

ssgvzors2#

正如其他人所指出的,睡眠的默认分辨率是10或15毫秒,这取决于Windows的版本。
但是,您可以通过发出

timeBeginPeriod(1);
timeEndPeriod(1);

其中

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

我们在串行通信服务中这样做,在这种服务中,能够准确地及时间隔发送是很重要的。有些人不愿意这样做,因为这会导致Windows更频繁地执行其他基于定时器的操作。实际上,这对我们来说没有造成明显的问题,我们有数百个安装,每个安装都连接了数百个串行设备。

izj3ouym

izj3ouym3#

微软C#保证了睡眠的最小时间。它睡眠少于5毫秒肯定是个问题。另外秒表可能测量不太精确,试试高精度的媒体计时器吧。

xbp102n0

xbp102n04#

它受系统时钟分辨率的影响。它大约是15ms ...你不能低于系统时钟的分辨率。看一下this链接(它是C++,但你会得到关于定时器分辨率的想法)。

a8jjtwal

a8jjtwal5#

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

scyqe7ek

scyqe7ek6#

这是一个Platform Dependent Wait,您可以在任何项目中使用它,只要将Thread挂起一段您指定的时间,并使用您的系统可以实现的最低分辨率(可能是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相同

相关问题