Slutt å blokkere WinForms mens proxy-sjekker kjører
Bytt ut en synkron Task.WaitAll i UI-hendelsesbehandleren med avventede, avgrensede partier, og oppdater deretter kontrollene i den gjenopptatte UI-konteksten.
Task.WaitAll i en WinForms-klikkbehandler blokkerer vinduet selv når sjekkene selv bruker asynkron HTTP. UI-tråden får ikke behandlet meldinger, og innfangede fortsettelser kan trenge den samme blokkerte tråden.
Med .NET 6 eller nyere venter du i stedet på et avgrenset parti:
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 et eksisterende skjema der System.Linq og System.Threading.Tasks er tilgjengelige. CheckProxyAsync utfører avgrenset asynkron inn- og utdata og returnerer ett resultat; den rører ikke kontroller fra en bakgrunnstråd. ShowResults og ShowCheckError er applikasjonsmetoder.
Den vanlige await-fortsettelsen går tilbake til UI-konteksten der behandleren startet, så ShowResults kan oppdatere kontroller. Kode som uttrykkelig kjører på en annen tråd, må sende kontrolltilgang gjennom den støttede WinForms-mekanismen.
Gratis proxy-liste kan skaffe inndataadresser; send bare protokoller som CheckProxyAsync implementerer. Åtte er et eksempelbudsjett. Neste parti venter på den langsomste sjekken i gjeldende parti, og bytter litt gjennomstrømning mot avgrenset oppgaveoppretting. Behold tidsfristene og kanselleringen for hver sjekk i CheckProxyAsync; å vente på et parti kan ikke få en ubegrenset nettverksoperasjon til å bli ferdig.