Task.WaitAll en un gestor de clics de WinForms bloqueja la finestra fins i tot quan les comprovacions mateixes fan servir HTTP asíncron. El fil de la UI no pot processar missatges, i les continuacions capturades poden necessitar aquest mateix fil bloquejat.

Per a .NET 6 o posterior, espera un lot limitat:

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

Això va en un formulari existent amb System.Linq i System.Threading.Tasks disponibles. CheckProxyAsync fa E/S asíncrona limitada i retorna un resultat; no manipula controls des d'un fil de fons. ShowResults i ShowCheckError són mètodes de l'aplicació.

La continuació normal de await torna al context de la UI on va començar el gestor, així que ShowResults pot actualitzar controls. El codi que s'executa explícitament en un altre fil ha de fer arribar l'accés als controls pel mecanisme compatible de WinForms.

La llista de proxys gratuïts pot proporcionar adreces d'entrada; passa només els protocols que implementa CheckProxyAsync. Vuit és un pressupost d'exemple. El lot següent espera la comprovació més lenta del lot actual, intercanviant part del rendiment per una creació de tasques limitada. Mantén els terminis de cada comprovació i la cancel·lació dins de CheckProxyAsync; esperar un lot no pot fer que una operació de xarxa il·limitada acabi.

Articles relacionats