Спрете блокирането на WinForms, докато текат проверки на прокси
Заменете синхронното Task.WaitAll в обработчика на UI събития с изчаквани ограничени партиди и след това обновете контролите в контекста на UI след възобновяване.
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; изчакването на партида не може да накара неограничена мрежова операция да завърши.