Требуется микросекундная задержка в приложении .NET для регулирования скорости многоадресной передачи UDP - PullRequest
7 голосов
/ 27 октября 2009

Я пишу пару клиент-сервер UDP многоадресной передачи в C #, и мне нужна задержка порядка 50-100 мкс (микросекунд), чтобы снизить скорость передачи сервера. Это помогает избежать значительной потери пакетов, а также помогает избежать перегрузки клиентов, связанных с дисковым вводом / выводом. Пожалуйста, не предлагайте Thread.Sleep или Thread.SpinWait. Я бы не спросил, нужен ли мне какой-либо из них.

Моей первой мыслью было использование какого-то высокопроизводительного счетчика и выполнение простого цикла while (), проверяющего истекшее время, но я бы хотел этого избежать, так как это кажется грязным. Не приведет ли это также к загрузке ЦП для серверного процесса?

Бонусные баллы за кроссплатформенное решение, то есть не для Windows. Заранее спасибо, ребята!

Ответы [ 6 ]

9 голосов
/ 27 октября 2009

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

Я бы описал поведение в классе следующим образом:

  • Создайте класс, статический конструктор которого запускает цикл вращения в течение нескольких миллионов итераций и фиксирует, сколько времени это займет. Это дает вам представление о том, сколько времени займет один цикл цикла для базового оборудования.
  • Вычисляет значение для США / итерации, которое можно использовать для вычисления произвольного времени ожидания.
  • При запросе на сон в течение определенного периода времени, делите США на сон на значение uS / итерации, предварительно рассчитанное, чтобы определить, сколько итераций цикла нужно выполнить.
  • Вращайте, используя цикл while, пока не истечет расчетное время.
7 голосов
/ 27 октября 2009

Я бы использовал секундомер , но понадобился бы цикл

прочитайте это , чтобы добавить дополнительное расширение к секундомеру, например ElapsedMicroseconds

или что-то подобное тоже может сработать

System.Diagnostics.Stopwatch.IsHighResolution ДОЛЖЕН быть верным

    static void Main(string[] args)
    {
        Stopwatch sw;
        sw = Stopwatch.StartNew();
        int i = 0;

        while (sw.ElapsedMilliseconds <= 5000)
        {
            if (sw.Elapsed.Ticks % 100 == 0)
            { i++; /* do something*/ }
        }
        sw.Stop();


    }
1 голос
/ 23 октября 2016
    static void udelay(long us)
    {
        var sw = System.Diagnostics.Stopwatch.StartNew();
        long v = (us * System.Diagnostics.Stopwatch.Frequency )/ 1000000;
        while (sw.ElapsedTicks < v)
        {
        }
    }
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            Console.WriteLine("" + i + " " + DateTime.Now.Second + "." + DateTime.Now.Millisecond);
            udelay(1000000);
        }
    }
1 голос
/ 01 апреля 2013

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

Я обнаружил, что лучшее решение - это таймеры MultiMedia, как показано в в этом примере .

Я использовал эту реализацию и добавил к ней асинхронный вызов TPL. Вы должны увидеть мой SimpleMulticastAnalyzer проект для получения дополнительной информации.

0 голосов
/ 08 марта 2013

Я бы не рекомендовал использовать спиновый цикл, поскольку он потребляет и создает блокирующий поток. Thread.sleep лучше, он не использует ресурсы процессора во время сна, он просто отрезает время. Попробуйте, и из диспетчера задач вы увидите, как загрузка ЦП резко возрастает при цикле вращения.

0 голосов
/ 27 октября 2009

Вы смотрели на мультимедийные таймеры ? Возможно, вы могли бы найти где-нибудь библиотеку .NET, которая где-то оборачивает вызовы API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...