atraso microssegundo necessidade em .NET app para estrangular taxa de transmissão de multicast UDP

StackOverflow https://stackoverflow.com/questions/1631501

Pergunta

Eu estou escrevendo um par cliente / servidor multicast UDP em C # e eu preciso de um atraso na ordem de 50-100 ms (microssegundos) para estrangular a taxa de transmissão do servidor. Isso ajuda a evitar a perda de pacote significativo e também ajuda a evitar sobrecarregar os clientes que estão disco I / O bound. Por favor, não sugerem Thread.Sleep ou Thread.SpinWait. Eu não iria perguntar se eu precisava de um desses.

Meu primeiro pensamento era usar algum tipo de contador de alta performance e fazer um simples loop while () verificar o tempo decorrido mas eu gostaria de evitar que, como ele se sente kludgey. Não que também peg a utilização da CPU para o processo do servidor?

Os pontos de bónus para uma solução multi-plataforma, ou seja, não o Windows específica. Agradecemos antecipadamente, guys!

Foi útil?

Solução

Gostaria de usar cronômetro mas seria necessário um laço

este para adicionar mais extensão para o cronômetro, como ElapsedMicroseconds

ou algo como este trabalho poder demasiado

System.Diagnostics.Stopwatch.IsHighResolution deve ser verdade

    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();


    }

Outras dicas

tempos de sono muito curtos são geralmente melhor alcançada por um loop de rotação de CPU (como o tipo que você descreve). Você geralmente quer evitar o uso das chamadas temporizador de alta precisão como eles próprios podem ocupar o tempo e distorcer os resultados. Eu não me preocuparia muito com CPU atrelar no servidor para esses tempos curtos de espera.

Gostaria de encapsular o comportamento em uma classe, como a seguir:

  • Crie uma classe cujo construtor estático é executado um ciclo de centrifugação durante vários milhões de iterações e capturas de quanto tempo leva. Isso lhe dá uma idéia de quanto tempo um único ciclo de loop iria assumir o hardware subjacente.
  • Compute um uS / iteração valor que você pode usar para calcular tempos de sono arbitrária.
  • Quando lhe pediram para dormir por um determinado período de tempo, nos dividir para dormir pelo valor de uS / iteração previamente calculado para identificar quantas iterações de loop para executar.
  • rotação usando um loop while até que os decorrido tempo estimado.

Eu experimentei com essa exigência quando eu precisava de mais precisão com o meu pedido multicast.

Descobri que os melhores reside solução com os temporizadores multimédia como visto em neste exemplo .

Eu usei essa implementação e acrescentou TPL assíncrono invocar a ele. Você deve ver meu projeto SimpleMulticastAnalyzer para obter mais informações.

    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);
        }
    }

Você já olhou para multimídia timers ? Você provavelmente poderia encontrar um lugar biblioteca .NET que envolve as chamadas de API em algum lugar.

Eu iria desencorajar utilizando loop rodada, uma vez que consome e cria bloqueando fio. Thread.sleep é melhor, ele não usa recursos do processador durante o sono, ele só cortar o tempo. Experimente, e você vai ver a partir gerenciador de tarefas como o uso de CPU pico com o ciclo de centrifugação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top