IT

C # 프로그램을 50msec 동안 절전 모드로 전환하려면 어떻게합니까?

lottoking 2020. 3. 29. 09:15
반응형

C # 프로그램을 50msec 동안 절전 모드로 전환하려면 어떻게합니까?


C # 프로그램을 50 밀리 초 동안 절전 모드로 전환하려면 어떻게합니까?

이것은 쉬운 질문처럼 보이지만 일시적인 뇌 장애 순간을 겪고 있습니다!


System.Threading.Thread.Sleep(50);

그러나 기본 GUI 스레드에서이 작업을 수행하면 GUI 업데이트가 차단됩니다 ( "느린 느낌").

;VB.net에서도 작동하도록하려면를 제거하십시오 .


기본적으로 프로그래밍 언어를 기다리는 방법은 3 가지가 있습니다.

  1. 느슨한 대기
    • 주어진 시간 동안 스레드 블록 실행 (= 처리 능력을 소비하지 않음)
    • 차단 / 대기 스레드에서 처리 할 수 ​​없습니다
    • 너무 정확하지
  2. 타이트 대기 (타이트 루프라고도 함)
    • 프로세서가 전체 대기 간격 동안 매우 사용 중입니다 (사실, 일반적으로 하나의 코어 처리 시간의 100 %를 소비 함)
    • 기다리는 동안 일부 작업을 수행 할 수 있습니다
    • 매우 정확한
  3. 이전 2의 조합
    • 일반적으로 1의 처리 효율성과 정확성 + 2의 기능을 수행합니다.

-C #에서 느슨하게 대기 :

Thread.Sleep(numberOfMilliseconds);

그러나 Windows 스레드 스케줄러는 정확도 Sleep()가 약 15ms가되도록합니다 (따라서 1ms 만 대기하도록 예약되어 있어도 Sleep은 20ms를 쉽게 기다릴 수 있습니다).

-C #에서 꽉 기다리는 것은 다음과 같습니다.

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do possible
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
}

우리는 또한 DateTime.Now다른 시간 측정 수단을 사용할 수도 있지만 Stopwatch훨씬 빠릅니다 (이것은 타이트한 루프에서 실제로 볼 수 있습니다).

3 인용-조합 :

Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
    //some other processing to do STILL POSSIBLE
    if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
    {
        break;
    }
    Thread.Sleep(1); //so processor can rest for a while
}

이 코드는 스레드를 1ms (또는 OS 스레드 스케줄링에 따라 약간 더) 동안 정기적으로 차단하므로 프로세서는 차단 시간 동안 사용 중이 아니며 코드는 프로세서 전력의 100 %를 소비하지 않습니다. UI 처리, 이벤트 처리 또는 상호 작용 / 통신 작업과 같은 다른 처리는 여전히 차단간에 수행 될 수 있습니다.


Windows 에서는 정확한 절전 시간을 지정할 수 없습니다 . 이를 위해서는 실시간 OS가 필요합니다. 최선의 방법은 최소 수면 시간을 지정하는 것입니다. 그런 다음 스레드를 깨우는 것은 스케줄러에 달려 있습니다. 그리고 GUI 스레드를 절대 호출 하지 마십시오.Sleep() .


이제 비동기 / 대기 기능이 있으므로 50ms 동안 절전 모드로 전환하는 가장 좋은 방법은 Task.Delay를 사용하는 것입니다.

async void foo()
{
    // something
    await Task.Delay(50);
}

또는 .NET 4 (VS2010 또는 Microsoft.Bcl.Async 용 Async CTP 3 사용)를 대상으로하는 경우 다음을 사용해야합니다.

async void foo()
{
    // something
    await TaskEx.Delay(50);
}

이렇게하면 UI 스레드를 차단하지 않습니다.


이 코드를 사용하십시오

using System.Threading;
// ...
Thread.Sleep(50);

Thread.Sleep(50);

스레드는 지정된 시간 동안 운영 체제에서 실행되도록 예약되지 않습니다. 이 메소드는 스레드 상태를 WaitSleepJoin을 포함하도록 변경합니다.

이 방법은 표준 COM 및 SendMessage 펌핑을 수행하지 않습니다. STAThreadAttribute가있는 스레드에서 휴면 상태를 유지해야하지만 표준 COM 및 SendMessage 펌핑을 수행하려는 경우 시간 초과 간격을 지정하는 Join 메서드의 오버로드 중 하나를 사용하는 것이 좋습니다.

Thread.Join

Thread.Sleep

가독성을 위해 :

using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));

두 세계의 최고:

using System.Runtime.InteropServices;

    [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
    private static extern uint TimeBeginPeriod(uint uMilliseconds);

    [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
    private static extern uint TimeEndPeriod(uint uMilliseconds);
    /**
     * Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
     */
    private void accurateSleep(int milliseconds)
    {
        //Increase timer resolution from 20 miliseconds to 1 milisecond
        TimeBeginPeriod(1);
        Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
        stopwatch.Start();

        while (stopwatch.ElapsedMilliseconds < milliseconds)
        {
            //So we don't burn cpu cycles
            if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
            {
                Thread.Sleep(5);
            }
            else
            {
                Thread.Sleep(1);
            }
        }

        stopwatch.Stop();
        //Set it back to normal.
        TimeEndPeriod(1);
    }

.NET Framework 4.5부터 다음을 사용할 수 있습니다.

using System.Threading.Tasks;

Task.Delay(50).Wait();   // wait 50ms

참고 URL : https://stackoverflow.com/questions/91108/how-do-i-get-my-c-sharp-program-to-sleep-for-50-msec

반응형