Какое влияние Thread.Sleep (1) в C #?

<head>
  

<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  
    <script type="text/javascript">
  

$(function() {
    $( "#dialog" ).dialog({
      autoOpen: false,
      show: {
        effect: "blind",
        duration: 1000
      },
      hide: {
        effect: "explode",
        duration: 1000
      }
    });
 
    $( "#opener" ).click(function() {
      $( "#dialog" ).dialog( "open" );
    });
  });
    </script>
</head>
<body>
   <div id="dialog" title="Basic dialog">
   <p>This is an animated dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
  </div>
 
  <button id="opener">Open Dialog</button>

</body>

29
задан Justin Tanner 3 February 2009 в 17:59
поделиться

10 ответов

Как уже говорилось, ваш цикл не будет загружать процессор.

Но будьте осторожны : Windows не ОС реального времени, поэтому вы не не получите 1000 пробуждений в секунду от Thread.Sleep ( 1). Если вы не использовали timeBeginPeriod для установки минимального разрешения, вы будете просыпаться каждые 15 мс. Даже после того, как вы установили минимальное разрешение в 1 мс, вы все равно будете просыпаться каждые 3-4 мс.

Для получения детализации таймера миллисекундного уровня необходимо использовать мультимедийный таймер Win32 (оболочка C # ).

43
ответ дан Bob Nadler 3 February 2009 в 17:59
поделиться

Нет, он не будет загружать процессор, он просто приостановит ваш поток на , по крайней мере, так долго. Пока ваш поток приостановлен, операционная система может запланировать другой, не связанный поток, чтобы использовать процессор.

28
ответ дан Frederick The Fool 3 February 2009 в 17:59
поделиться

Следует избегать небольшого времени ожидания, так как поток, отказывающийся от своего временного интервала, получает повышение приоритета при повторном сигнале, что может привести к высоким переключениям контекста. В многопоточных / серверных приложениях это может привести к нежелательному эффекту, поскольку потоки борются за процессорное время. Вместо этого полагайтесь на асинхронные функции и объекты синхронизации, такие как критические секции или мьютексы / семафоры.

4
ответ дан Tim Lehner 3 February 2009 в 17:59
поделиться

Как отметил Боб Надлер Thread.Sleep(1), время сна не гарантируется 1 мс.

Вот пример использования мультимедийного таймера Win32 для принудительного ожидания 1 мс.

    [DllImport("winmm.dll")]
    internal static extern uint timeBeginPeriod(uint period);
    [DllImport("winmm.dll")]
    internal static extern uint timeEndPeriod(uint period);

    timeBeginPeriod(1);
    while(true)
    {
        Thread.Sleep(1); // will sleep 1ms every time
    }
    timeEndPeriod(1);

Тестируя это в C # GUI-приложении, я обнаружил, что приложение использует около 50% моего процессора.

Для получения дополнительной информации по этой теме см. Следующую ветку форума:

http://www.dotnet247.com/247reference/msgs/57/289291.aspx

4
ответ дан Justin Tanner 3 February 2009 в 17:59
поделиться

Thread.Sleep (1), как указано, не будет загружать процессор.

Вот что происходит, когда поток спит (более или менее):

  • Thread.Sleep преобразуется в системный вызов, который, в свою очередь, вызывает прерывание (прерывание, которое позволяет операционной системе) взять на себя управление)
  • Операционная система обнаруживает вызов в спящий режим и помечает ваш поток как заблокированный.
  • Внутри ОС хранит список потоков, которые необходимо активировать и когда это должно произойти.
  • Поскольку поток больше не использует процессор ОС ...
  • Если родительский процесс не использовал весь свой временной интервал, ОС запланирует выполнение другого потока процесса.
  • В противном случае другой процесс (или простой процесс) начнет выполняться.
  • Когда наступит время, ваш поток будет снова запланирован для выполнения, это не значит, что он начнет выполняться автоматически.

В заключение отметим, что я точно не знаю, что вы делаете, но может показаться, что вы пытаетесь взять на себя роль планировщика, то есть спящего, чтобы предоставить процессору время для выполнения других задач. вещи ...

В некоторых случаях (очень мало) это может быть хорошо, но в основном вы должны позволить планировщику выполнять свою работу, он, вероятно, знает больше, чем вы , и может сделать работать лучше, чем вы можете сделать это .

19
ответ дан Jorge Córdoba 3 February 2009 в 17:59
поделиться

Нет, он не будет загружать весь доступный ЦП, потому что планировщик ОС отключит спящий поток, когда другой поток будет работать.

2
ответ дан TheSmurf 3 February 2009 в 17:59
поделиться

Это старый поток, который встречается во многих моих поисках, но в Win7 появился новый планировщик, и, похоже, он ведет себя не так, как описано выше.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtEnd = DateTime.Now.AddSeconds(1.0);
            int i = 0;
            while (DateTime.Now < dtEnd)
            {
                i++;
                Thread.Sleep(1);
            }

            Console.WriteLine(i.ToString());

            i = 0;
            long lStart = DateTime.Now.Ticks;
            while (i++ < 1000)
                Thread.Sleep(1);

            long lTmp = (DateTime.Now.Ticks - lStart) / 10000;

            Console.WriteLine(lTmp.ToString());

            Console.Read();
        }
    }
}

С помощью приведенного выше кода мой первый результат дал 946. Таким образом, за промежуток времени в 1 секунду при использовании сна в 1 мс я получил 946 пробуждений. Это очень близко к 1 мс.

Вторая часть спрашивает, сколько времени требуется, чтобы выполнить 1000 событий сна при 1 мс каждый. Я получил 1034 мс. Опять же, почти 1 мс.

Это было на 1,8 ГГц core2duo + Win7 с использованием .Net 4.0

Редактировать: запомните, сон (x) не означает, что вы просыпаетесь в это время, это значит, разбудите меня не раньше этого время. Это не гарантировано. Хотя вы можете увеличить приоритет потока, и Windows должна запланировать ваш поток до потоков с более низким приоритетом.

3
ответ дан Bengie 3 February 2009 в 17:59
поделиться

Нет, не будет. Ты едва увидишь это. Где-то менее 1000 раз в секунду эта нить просыпается и почти ничего не делает, прежде чем снова заснуть.

Редактировать:

Я должен был проверить. Работая на Java 1.5, этот тест

@Test
public void testSpeed() throws InterruptedException {
    long currentTime = System.currentTimeMillis();
    int i = 0;
        while (i < 1000)
        {
            Thread.sleep(1);
            i++;
        }
    System.out.println("Executed in " + (System.currentTimeMillis() - currentTime));
}

выполнялся со скоростью примерно 500 снов в секунду на моей 3-ГГц машине. Я полагаю, что C # должен быть примерно таким же. Я предполагаю, что кто-то сообщит с номерами C # для этого чрезвычайно важного реального эталонного теста. Между прочим, не было заметного использования процессора.

2
ответ дан krosenvold 3 February 2009 в 17:59
поделиться

Поток может максимально загружать один (логический) процессор за один раз. И сон в 1 мс не будет мешать. Не парься.

0
ответ дан Andrei Rînea 3 February 2009 в 17:59
поделиться

также посмотрите на это: msdn forum

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace Test
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();

            for (int i = 0; i < 10; ++i)
            {
                sw.Reset();
                sw.Start();
                Thread.Sleep(50);
                sw.Stop();

                Console.WriteLine("(default) Slept for " + sw.ElapsedMilliseconds);

                TimeBeginPeriod(1);
                sw.Reset();
                sw.Start();
                Thread.Sleep(50);
                sw.Stop();
                TimeEndPeriod(1);

                Console.WriteLine("(highres) Slept for " + sw.ElapsedMilliseconds + "\n");
            }
        }

        [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);
    }
}
0
ответ дан FrankyHollywood 3 February 2009 в 17:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: