Task.WaitAll v obsluhe kliknutia WinForms blokuje okno, aj keď samotné kontroly používajú asynchrónny HTTP. Vlákno UI nemôže spracúvať správy a zachytené pokračovania môžu potrebovať to isté zablokované vlákno.

V .NET 6 alebo novšom namiesto toho čakajte na obmedzenú 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;
    }
}

Toto patrí do existujúceho formulára s dostupnými System.Linq a System.Threading.Tasks. CheckProxyAsync vykonáva obmedzené asynchrónne vstupy a výstupy a vracia jeden výsledok; nemanipuluje s ovládacími prvkami z vlákna na pozadí. ShowResults a ShowCheckError sú metódy aplikácie.

Bežné pokračovanie await sa vracia do kontextu UI, kde obsluha začala, takže ShowResults môže aktualizovať ovládacie prvky. Kód, ktorý explicitne beží v inom vlákne, musí odovzdávať prístup k ovládacím prvkom cez podporovaný mechanizmus WinForms.

Zoznam bezplatných proxy môže poskytnúť vstupné adresy; odovzdávajte iba protokoly implementované v CheckProxyAsync. Osem je príklad rozpočtu. Ďalšia dávka čaká na najpomalšiu kontrolu v aktuálnej dávke a vymieňa časť priepustnosti za obmedzené vytváranie úloh. Zachovajte termíny každej kontroly a zrušenie v CheckProxyAsync; čakanie na dávku nemôže spôsobiť, že sa neobmedzená sieťová operácia dokončí.

Súvisiace články