Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

368
Vistas
¿Cómo ejecutar una tarea en un nuevo hilo e inmediatamente volver a la persona que llama?

Durante los últimos meses he estado leyendo sobre async-await en C# y cómo usarlo correctamente.

Con el propósito de un ejercicio de laboratorio, estoy construyendo un pequeño servidor Tcp que debería servir a los clientes que se conectan a él. El programa es una aplicación de consola.

Uso un ciclo while para esperar conexiones como esta:

 while (!_isStopRequested) { TcpClient client = await _tcpListener.AcceptTcpClientAsync(); await Task.Factory.StartNew(() => ProcessClientAsync(client), TaskCreationOptions.LongRunning); }

Entonces, hasta ahora, el método ProcessClientAsync que hice estaba marcado como vacío asíncrono y simplemente lo llamaría ProcessClientAsync(cliente) y la llamada regresaría inmediatamente a la persona que llamó. Sin embargo, leí en Internet que es una mala decisión usarlo a menos que sea para un evento. Así que cambié la definición a Tarea asíncrona.

Ok, pero sin espera, recibo una advertencia en Visual Studio "Debido a que esta llamada no se espera, el método actual continúa ejecutándose antes de que se complete la llamada".

Y una vez que usé await ProcessClientAsync (cliente), el código no funciona. Puedo conectar solo un cliente, y luego la persona que llama "espera" a que regrese ProcessClientAsync. Sin embargo, ese método tiene un ciclo infinito y no regresará, pero necesito el ciclo while para continuar procesando el siguiente cliente.

Buscando en Google llegué a este hilo: Cómo llamar de forma segura a un método asíncrono en C# sin esperar

Supongo que las preguntas son más o menos las mismas, excepto que cuando uso await ProcessClientAsync, quiero que regrese a la persona que llama de inmediato, lo cual no sucede, lo sé porque ejecuto el segundo cliente, mientras que el primero aún se está ejecutando. el segundo cliente no se conecta.

Así que hice esto:

 await Task.Factory.StartNew(() => ProcessClientAsync(client), TaskCreationOptions.LongRunning);

Pero dado que ProcessClientAsync tiene que devolver una Tarea, no estoy seguro de si está bien hacerlo.

Esa sería una pregunta.

El otro sería: ¿cómo podría llamar a un método de tarea asíncrono que se ejecutará para siempre y hacer que la llamada regrese a la persona que llama de inmediato para que el ciclo while pueda continuar y el oyente tcp pueda continuar aceptando al siguiente cliente?

Gracias.

Lo siento si es una repetición, o si no está claro lo que estoy preguntando.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Con el propósito de un ejercicio de laboratorio, estoy construyendo un pequeño servidor Tcp que debería servir a los clientes que se conectan a él. El programa es una aplicación de consola.

Bueno, lo primero que recomendaría es probar un ejercicio más simple. En serio, un servidor TCP asíncrono es una de las aplicaciones más complejas que puede elegir. La gran mayoría de los desarrolladores que usan async están trabajando en aplicaciones dos órdenes de magnitud más simples.

En lugar de eso, intente escribir una aplicación de interfaz de usuario que descargue un archivo desde una URL. Ese es un punto de partida más realista para aprender async .

Pero dado que ProcessClientAsync tiene que devolver una Tarea, no estoy seguro de si está bien hacerlo.

Recomiendo usar Task.Run en lugar de Task.Factory.StartNew . Task.Run es consciente de los métodos async , mientras que StartNew no lo es.

Sin embargo, eso supone que iniciar un hilo es la operación correcta en primer lugar. La mayoría de las aplicaciones de servidor TCP/IP no están vinculadas a la CPU, por lo que cuestiono el uso de múltiples subprocesos aquí. Es completamente posible tener un servidor TCP/IP totalmente asíncrono que solo use el grupo de subprocesos para sus continuaciones de método async .

El otro sería: ¿cómo podría llamar a un método de tarea asíncrono que se ejecutará para siempre y hacer que la llamada regrese a la persona que llama de inmediato para que el ciclo while pueda continuar y el oyente tcp pueda continuar aceptando al siguiente cliente?

Simplemente no await la Task que devuelve:

 Task.Run(() => ProcessClientAsync(client));

Sin embargo, el compilador se quejará aquí, porque es casi seguro que este código es incorrecto. Si ignora la tarea devuelta, está ignorando cualquier excepción de ese código.

Un patrón común en las aplicaciones de servidor TCP/IP es mantener una pequeña colección de estado para cada cliente conectado. Ese es un lugar natural para colocar tanto el objeto de socket como la tarea que representa el manejo de esa conexión de socket:

 var clientState = new ClientState(client); clientState.Task = Task.Run(() => ProcessClientAsync(client));

Estos estados de cliente se almacenan en una lista/diccionario. Cómo haces esto exactamente, por supuesto, depende de ti.

over 4 years ago · Santiago Trujillo Denunciar

0

Esto iniciará la tarea y regresará a la persona que llama, y evitará la advertencia del compilador:

 var t = Task.Factory.StartNew(() => {});
over 4 years ago · Santiago Trujillo Denunciar

0

Si estoy en lo correcto, entiendo su problema, entonces este código debería ayudar:

 private async void AcceptClient(TcpClient client) { await Task.Factory.StartNew(() => ProcessClientAsync(client), TaskCreationOptions.LongRunning); } private async void Run() { while (!_isStopRequested) { TcpClient client = await _tcpListener.AcceptTcpClientAsync(); AcceptClient(client); } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda