Stop med at blokere WinForms, mens proxykontroller kører
Erstat en synkron Task.WaitAll i UI-begivenhedshåndteringen med afventede, afgrænsede batches, og opdater derefter kontrollerne i den genoptagne UI-kontekst.
Task.WaitAll i en WinForms-klikhåndtering blokerer vinduet, selv når kontrollerne selv bruger asynkron HTTP. UI-tråden kan ikke behandle meddelelser, og opfangede fortsættelser kan få brug for den samme blokerede tråd.
For .NET 6 eller nyere skal du i stedet afvente en afgrænset 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;
}
}Dette hører til i en eksisterende form med System.Linq og System.Threading.Tasks tilgængelige. CheckProxyAsync udfører afgrænset asynkron I/O og returnerer ét resultat; den manipulerer ikke kontroller fra en baggrundstråd. ShowResults og ShowCheckError er applikationsmetoder.
Den normale await-fortsættelse vender tilbage til den UI-kontekst, hvor håndteringen begyndte, så ShowResults kan opdatere kontroller. Kode, der udtrykkeligt kører på en anden tråd, skal sende kontroladgang gennem den understøttede WinForms-mekanisme.
Den gratis proxyliste kan levere inputadresser; send kun protokoller, som CheckProxyAsync implementerer. Otte er et eksempelbudget. Den næste batch venter på den langsomste kontrol i den aktuelle batch og bytter noget gennemløb for afgrænset opgaveoprettelse. Behold hver kontrols deadlines og annullering i CheckProxyAsync; at afvente en batch kan ikke få en ubegrænset netværksoperation til at afslutte.