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 извършва ограничен асинхронен I/O и връща един резултат; не манипулира контроли от фонова нишка. ShowResults и ShowCheckError са методи на приложението.

Нормалното продължение на await се връща в контекста на UI, където е започнал манипулаторът, така че ShowResults може да обновява контроли. Код, който явно работи на друга нишка, трябва да предава достъпа до контроли чрез поддържания механизъм на WinForms.

Безплатният списък с проксита може да предоставя входни адреси; предавайте само протоколи, реализирани от CheckProxyAsync. Осем е примерен бюджет. Следващата партида изчаква най-бавната проверка в текущата партида, като разменя част от пропускливостта срещу ограничено създаване на задачи. Пазете крайните срокове на всяка проверка и отмяната в CheckProxyAsync; изчакването на партида не може да накара неограничена мрежова операция да завърши.

Подобни статии