Task.WaitAll в обробнику клацання WinForms блокує вікно, навіть коли самі перевірки використовують асинхронний HTTP. Потік UI не може обробляти повідомлення, а захопленим продовженням може знадобитися той самий заблокований потік.

Для .NET 6 або новішої версії натомість очікуйте обмежений пакет:

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

Це належить до наявної форми з доступними System.Linq і System.Threading.Tasks. CheckProxyAsync виконує обмежений асинхронний ввід і вивід та повертає один результат; вона не керує елементами керування з фонового потоку. ShowResults і ShowCheckError — методи застосунку.

Звичайне продовження await повертається до контексту UI, де почався обробник, тож ShowResults може оновлювати елементи керування. Код, що явно виконується в іншому потоці, має передавати доступ до елементів керування через підтримуваний механізм WinForms.

Список безкоштовних proxy може надати вхідні адреси; передавайте лише протоколи, реалізовані в CheckProxyAsync. Вісім — це приклад бюджету. Наступний пакет чекає на найповільнішу перевірку в поточному пакеті, обмінюючи частину пропускної здатності на обмежене створення задач. Зберігайте терміни кожної перевірки та скасування в CheckProxyAsync; очікування пакета не може змусити необмежену мережеву операцію завершитися.

Схожі статті