Проблемы с использованием Thread.Sleep в течение короткого времени

У меня есть приложение с двумя потоками (сейчас), но кажется, что функция 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
}

Также я пробовал засыпать его секундомером в функции уток и тоже занимает больше времени:

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

Пожалуйста помоги.


person matej148    schedule 13.01.2012    source источник
comment
Да, Thread.Sleep не гарантируется, что он будет спать ровно указанное количество времени. И вообще его использование — признак того, что ваше приложение плохо спроектировано. Непонятно, какую проблему вы пытаетесь решить с его помощью. Попробуйте дополнить свой вопрос обсуждением реальной проблемы, а не неудачного решения.   -  person Cody Gray    schedule 13.01.2012
comment
Я отправляю огромное количество пакетов с помощью sharppcap и packetdotnet (имитация DoS-атаки [дипломная работа]), и я хочу смоделировать ее с небольшими задержками между пакетами (без задержки/задержки 5 мс/задержки 10 мс...).   -  person matej148    schedule 13.01.2012


Ответы (5)


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

Так что действительно трудно добиться большего, на самом деле, 20 или 30 мс более вероятны. Раньше я выполнял обработку в реальном времени с жестким ограничением в 50 мс. Это хорошо работало в Windows, если вы соблюдали определенные правила (это было в C++)

person Keith Nicholas    schedule 13.01.2012
comment
Есть ли какая-нибудь статья в MSDN, подтверждающая это? - person PawanS; 25.09.2013
comment
Это для Task.Delay, но, вероятно, то же самое касается Thread.Sleep... msdn.microsoft.com/en-us/library/hh194845(v=vs.110).aspx - person Binier; 07.09.2017

Как указывали другие, разрешение сна по умолчанию составляет 10 или 15 миллисекунд, в зависимости от версии Windows.

Однако вы можете перепрограммировать таймер для использования разрешения в 1 миллисекунду, введя

timeBeginPeriod(1);
timeEndPeriod(1);

куда

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

Мы делаем это в наших службах последовательной связи, где важна возможность точного распределения времени отправки. Некоторые люди не хотят этого делать, потому что это заставляет Windows чаще выполнять другие действия, основанные на таймере. На самом деле это не вызвало у нас заметных проблем, и у нас есть сотни установок, каждая из которых связана с сотнями последовательных устройств.

person 500 - Internal Server Error    schedule 13.01.2012
comment
Это не было бы проблемой на выделенной машине, но я бы вряд ли рекомендовал ее для общего использования. И если бы ваш установщик когда-нибудь сделал это с моей машиной, я бы, наверное, отправил почтой. Более того, это все еще не гарантирует, что таймер действительно использует разрешение в 1 миллисекунду. Windows по-прежнему не является операционной системой реального времени. - person Cody Gray; 13.01.2012
comment
Это специализированные машины. И вы, конечно, правы, что это не меняет того факта, что Windows не является ОС реального времени. - person 500 - Internal Server Error; 13.01.2012
comment
Похоже, вы также должны вызывать timeEndPeriod — вы должны сопоставлять каждый вызов timeBeginPeriod с вызовом timeEndPeriod, указывая одинаковое минимальное разрешение в обоих вызовах. msdn.microsoft.com/en -нас/библиотека/окна/рабочий стол/ - person Matt; 13.03.2018

Сон в Microsoft C# гарантирует минимальное количество времени. Если он спит менее 5 миллисекунд, это определенно проблема. Также секундомер может быть не очень точным измерением, попробуйте высокоточные медиа-таймеры.

person nmjohn    schedule 13.01.2012
comment
Я не согласен с тем, что секундомер обеспечит высокую точность синхронизации, как и медиа-таймеры. Насколько я знаю, это тот же таймер, который используют таймеры мультимедиа, который является QueryPerformanceCounter. Я не знаю другого таймера с высоким разрешением на стандартном ПК с Windows. - person galford13x; 21.05.2013

На это влияет разрешение системных часов. Это около 15 мс ... вы не можете опуститься ниже разрешения системных часов. Взгляните на эту ссылку (это C++, но вы поймете, о разрешениях таймера).

person Aleksandar Vucetic    schedule 13.01.2012

Параметр, передаваемый в Thread.Sleep, — это минимальное время сна, а не точное время.

person brianestey    schedule 13.01.2012