Deja de bloquear WinForms mientras se ejecutan las comprobaciones de proxy
Sustituye el Task.WaitAll síncrono del controlador de eventos de la UI por lotes limitados esperados y luego actualiza los controles en el contexto de UI reanudado.
Task.WaitAll en un controlador de clic de WinForms bloquea la ventana incluso cuando las propias comprobaciones usan HTTP asíncrono. El hilo de la UI no puede procesar mensajes, y las continuaciones capturadas pueden necesitar ese mismo hilo bloqueado.
En .NET 6 o posterior, espera en su lugar un lote limitado:
private async void checkButton_Click(object sender, EventArgs e)
{
checkButton.Enabled = false;
try
{
var entries = proxyList.Lines
.Where(line => !string.IsNullOrWhiteSpace(line));
foreach (var batch in entries.Chunk(8))
{
var results = await Task.WhenAll(batch.Select(CheckProxyAsync));
ShowResults(results);
}
}
catch (Exception error)
{
ShowCheckError(error);
}
finally
{
checkButton.Enabled = true;
}
}Esto va en un formulario existente con System.Linq y System.Threading.Tasks disponibles. CheckProxyAsync realiza E/S asíncrona limitada y devuelve un resultado; no manipula controles desde un hilo en segundo plano. ShowResults y ShowCheckError son métodos de la aplicación.
La continuación normal de await vuelve al contexto de UI donde comenzó el controlador, así que ShowResults puede actualizar controles. El código que se ejecuta explícitamente en otro hilo debe organizar el acceso a los controles mediante el mecanismo compatible de WinForms.
La lista de proxies gratuitos puede proporcionar direcciones de entrada; pasa solo los protocolos que implementa CheckProxyAsync. Ocho es un presupuesto de ejemplo. El siguiente lote espera la comprobación más lenta del lote actual, intercambiando algo de rendimiento por una creación de tareas limitada. Mantén los plazos de cada comprobación y la cancelación dentro de CheckProxyAsync; esperar un lote no puede hacer que una operación de red ilimitada termine.