Task.WaitAll v obslužné rutině kliknutí WinForms blokuje okno, i když samotné kontroly používají asynchronní HTTP. Vlákno UI nemůže zpracovávat zprávy a zachycená pokračování mohou potřebovat stejné blokované vlákno.

Pro .NET 6 nebo novější místo toho počkejte na omezenou dávku:

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

To patří do existujícího formuláře s dostupnými System.Linq a System.Threading.Tasks. CheckProxyAsync provádí omezené asynchronní I/O a vrací jeden výsledek; nemanipuluje ovládacími prvky z vlákna na pozadí. ShowResults a ShowCheckError jsou metody aplikace.

Normální pokračování await se vrací do kontextu UI, kde obslužná rutina začala, takže ShowResults může aktualizovat ovládací prvky. Kód explicitně běžící v jiném vlákně musí předávat přístup k ovládacím prvkům podporovaným mechanismem WinForms.

Seznam bezplatných proxy může poskytnout vstupní adresy; předávejte pouze protokoly implementované CheckProxyAsync. Osm je příklad rozpočtu. Další dávka čeká na nejpomalejší kontrolu v aktuální dávce a vyměňuje část propustnosti za omezené vytváření úloh. Uchovávejte termíny každé kontroly a zrušení v CheckProxyAsync; čekání na dávku nemůže dokončit neomezenou síťovou operaci.

Související články