El puerto no se libera tan pronto como el programa sale en C# .NET Core.
Tengo una aplicación de consola C# .net core 3.1 que actúa como un servidor web REST. Se ejecuta como un servicio de Windows. Funciona bien, pero después de apagar la aplicación (o cuando se detiene durante una operación), no puedo iniciar la aplicación de inmediato. Recibo el siguiente error:
No se puede iniciar Kestrel. System.IO.IOException: Error al enlazar a la dirección http://[::]:8000: la dirección ya está en uso.
---> Microsoft.AspNetCore.Connections.AddressInUseException: Normalmente está permitido un solo uso de cada dirección de socket (protocolo/red/dirección/puerto).
--->System.Net.Sockets.SocketException(10048): Normalmente está permitido un solo uso de cada dirección de socket (protocolo/red/dirección/puerto).
.
.
.
Si intento después de unos 5 minutos aproximadamente, puedo iniciar la aplicación. ¿Hay algo que deba hacer o que pueda hacer para liberar la asignación en el puerto antes de detenerme en la aplicación?
Actualización – 1
Utilizo lo siguiente para apagar la aplicación en caso de errores, etc.
_hostLifetime.StopApplication();
Este es el código que inicializa el servidor web:
webBuilder.UseStartup<Startup>().UseUrls(restPort.Value);
El constructor de la clase Startup es el siguiente:
_httpListener = new HttpListener();
El método Configure
en la clase Startup tiene el siguiente código:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
davy.ai
Parece que la aplicación no está liberando los recursos en el puerto cuando se detiene, lo que provoca el error “dirección ya en uso” al intentar iniciar la aplicación inmediatamente después de detenerla.
Una solución podría ser detener explícitamente el servidor web antes de apagar la aplicación. Esto se puede hacer agregando un gancho en el evento de detención del servicio. En el archivo
Program.cs
, modifique el métodoCreateHostBuilder
para agregar el evento de detención de esta manera:Esto debería asegurarse de que el servidor web se detenga correctamente antes de que la aplicación se apague, liberando los recursos en el puerto.
Otra opción es capturar la excepción
AddressInUseException
en el archivoProgram.cs
y volver a intentar iniciar la aplicación después de un retraso, de esta manera:Este enfoque agrega un mecanismo de reintento para iniciar el servidor web, esperando un retraso antes de volver a intentar iniciar si el puerto ya está en uso. El número máximo de intentos y el retraso se pueden configurar según los requisitos de la aplicación.