Stop met het blokkeren van WinForms terwijl proxycontroles draaien
Vervang een synchrone Task.WaitAll in de UI-gebeurtenishandler door awaited, begrensde batches en werk daarna de besturingselementen bij op de hervatte UI-context.
Task.WaitAll in een WinForms-klikhandler blokkeert het venster, zelfs wanneer de controles zelf asynchrone HTTP gebruiken. De UI-thread kan geen berichten verwerken, en vastgelegde continuations kunnen diezelfde geblokkeerde thread nodig hebben.
Voor .NET 6 of later wacht je in plaats daarvan op een begrensde batch:
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;
}
}Dit hoort in een bestaand formulier met System.Linq en System.Threading.Tasks beschikbaar. CheckProxyAsync doet begrensde asynchrone invoer en uitvoer en retourneert een resultaat; het manipuleert geen besturingselementen vanuit een achtergrondthread. ShowResults en ShowCheckError zijn applicatiemethoden.
De normale await-continuation keert terug naar de UI-context waar de handler begon, zodat ShowResults de besturingselementen kan bijwerken. Code die expliciet op een andere thread draait, moet toegang tot besturingselementen doorgeven via het ondersteunde WinForms-mechanisme.
De gratis proxylijst kan invoeradressen leveren; geef alleen protocollen door die CheckProxyAsync implementeert. Acht is een voorbeeldbudget. De volgende batch wacht op de traagste controle in de huidige batch en ruilt wat doorvoer in voor begrensde taakcreatie. Houd de deadlines van elke controle en annulering in CheckProxyAsync; wachten op een batch kan een onbegrensde netwerkbewerking niet laten voltooien.