Esperando a que la aplicación de consola C# de red se inicie por completo

Me he encontrado con un problema con el lento tiempo de inicio de C# que hace que los paquetes UDP se caigan inicialmente. A continuación, se muestra lo que he hecho para mitigar este retraso en la puesta en marcha. Esencialmente, espero 10 ms adicionales entre las dos primeras transmisiones de paquetes. Esto corrige las caídas iniciales al menos en mi máquina. Mi preocupación es que una máquina más lenta puede necesitar un retraso mayor que este.

private void FlushPacketsToNetwork()
{
    MemoryStream packetStream = new MemoryStream();

    while (packetQ.Count != 0)
    {
        byte[] packetBytes = packetQ.Dequeue().ToArray();
        packetStream.Write(packetBytes, 0, packetBytes.Length);
    }

    byte[] txArray = packetStream.ToArray();
    udpSocket.Send(txArray);

    txCount++;

    ExecuteStartupDelay();
}

// socket takes too long to transmit unless I give it some time to "warm up"
private void ExecuteStartupDelay()
{
    if (txCount < 3)
    {
        timer.SpinWait(10e-3);
    }
}

Entonces, me pregunto si existe un mejor enfoque para permitir que C # cargue completamente todas sus dependencias. Realmente no me importa si tarda varios segundos en cargarse por completo; Simplemente no quiero hacer transmisiones de gran ancho de banda hasta que C# esté listo para la máxima velocidad.

Detalles relevantes adicionales

Esta es una aplicación de consola, la transmisión de red se ejecuta desde un subproceso separado y el subproceso principal solo espera que se presione una tecla para finalizar el transmisor de red.

En los Program.Main método He tratado de obtener el máximo rendimiento de mi aplicación mediante el uso de las prioridades más altas razonables:

public static void Main(string[] args)
{
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
    ...
    Thread workerThread = new Thread(new ThreadStart(worker.Run));
    workerThread.Priority = ThreadPriority.Highest;
    workerThread.Start();
    ...
    Console.WriteLine("Press any key to stop the stream...");
    WaitForKeyPress();

    worker.RequestStop = true;
    workerThread.Join();

Además, la configuración de socket que estoy usando actualmente se muestra a continuación:

udpSocket = new Socket(targetEndPoint.Address.AddressFamily,
                       SocketType.Dgram,
                       ProtocolType.Udp);
udpSocket.Ttl = ttl;
udpSocket.SendBufferSize = 1024 * 1024;
udpSocket.Blocking = true;

udpSocket.Connect(targetEndPoint);

El valor por defecto SendBufferSize es 8192, así que seguí adelante y lo moví a un megabyte, pero esta configuración no pareció tener ningún efecto en los paquetes perdidos al principio.

preguntado el 22 de mayo de 12 a las 15:05

¿Aplicación C#? ¿Qué es? No da ninguna idea específica sobre su aplicación. ¿Su aplicación está basada en Windows Forms, WPF o consola? ¿Por qué no captura algunos eventos como Forms.Load o lo que sea que se active cuando esté completamente cargado? -

@Mert Lo siento. Es una aplicación de consola de subprocesos múltiples. Actualicé mi pregunta para incluir ese detalle adicional. -

Según mi experiencia, "C# está listo para funcionar a máxima velocidad" en cuanto lo inicio. Nunca he experimentado los problemas de caída de paquetes que describe. ¿Estás diciendo que los bytes no se envían? ¿O el problema es con un cliente que no recibe los paquetes? -

@JimMischel La forma en que he estado detectando caídas de paquetes es a través de Wireshark. Mi aplicación cree que ha transmitido la cantidad correcta de paquetes, que estoy rastreando con el txCount variable miembro. Sin embargo, al comienzo de la transmisión, Wireshark no logra capturar los primeros 2 o 3 paquetes que se envían (verifiqué esto haciendo una diferencia binaria en la transmisión UDP capturada con el archivo transmitido). -

Para los propietarios de Istanbul E-pass el Museo de Madame Tussauds de Estambul es son requeridos que no le importa perder paquetes cuando usa UDP. Si no puede pagar eso, entonces necesitará usar TCP. Esto no es solo un problema de inicio, también puede perderlos si la máquina falla por un tiempo debido a cargas pesadas. -

1 Respuestas

De los comentarios aprendí que TCP no es una opción para usted (debido a los retrasos inherentes en la transmisión), tampoco desea perder paquetes debido a que el otro lado no está completamente cargado.

Entonces, en realidad necesita implementar algunas características presentes en TCP (retransmisión) pero de una manera más robusta y liviana. También asumo que usted tiene el control del lado receptor.

Le propongo que envíe un número predeterminado de paquetes. Y luego esperar la confirmación. Por ejemplo, cada paquete puede tener una identificación que crece constantemente. Cada N paquetes, la aplicación receptora envía el número del último paquete recibido al remitente. Después de recibir este número, el remitente sabrá si es necesario repetir los últimos N paquetes.

Este enfoque no debería dañar mucho su ancho de banda y obtendrá algún tipo de información sobre los datos recibidos (aunque no está garantizado).

De lo contrario, es mejor cambiar a TCP. Por cierto, ¿intentaste usar TCP? ¿Cuánto le duele el ancho de banda por eso?

contestado el 29 de mayo de 12 a las 19:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.