Sluta blockera WinForms medan proxykontroller körs
Byt ut en synkron Task.WaitAll i UI-händelsehanteraren mot inväntade, begränsade batcher och uppdatera sedan kontrollerna i den återupptagna UI-kontexten.
Task.WaitAll i en WinForms-klickhanterare blockerar fönstret även när kontrollerna själva använder asynkron HTTP. UI-tråden kan inte bearbeta meddelanden, och fångade fortsättningar kan behöva samma blockerade tråd.
För .NET 6 eller senare, invänta en begränsad batch i stället:
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;
}
}Detta hör hemma i ett befintligt formulär med System.Linq och System.Threading.Tasks tillgängliga. CheckProxyAsync utför begränsad asynkron in- och utmatning och returnerar ett resultat; den manipulerar inte kontroller från en bakgrundstråd. ShowResults och ShowCheckError är applikationsmetoder.
Den vanliga await-fortsättningen återgår till UI-kontexten där hanteraren började, så ShowResults kan uppdatera kontroller. Kod som uttryckligen körs på en annan tråd måste skicka kontrollåtkomst via den stödda WinForms-mekanismen.
Gratis proxylista kan leverera indataadresser; skicka bara protokoll som CheckProxyAsync implementerar. Åtta är en exempelbudget. Nästa batch väntar på den långsammaste kontrollen i den aktuella batchen och byter lite genomströmning mot begränsad uppgiftsskapning. Behåll varje kontrolls tidsfrister och avbrytande i CheckProxyAsync; att invänta en batch kan inte få en obegränsad nätverksoperation att slutföras.