Přestaňte blokovat WinForms během běhu kontrol proxy
Nahraďte synchronní Task.WaitAll v obslužné rutině události UI očekávanými omezenými dávkami a poté aktualizujte ovládací prvky v obnoveném kontextu UI.
Task.WaitAll v obslužné rutině kliknutí WinForms blokuje okno, i když samotné kontroly používají asynchronní HTTP. Vlákno UI nemůže zpracovávat zprávy a zachycená pokračování mohou potřebovat stejné blokované vlákno.
Pro .NET 6 nebo novější místo toho počkejte na omezenou dávku:
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;
}
}To patří do existujícího formuláře s dostupnými System.Linq a System.Threading.Tasks. CheckProxyAsync provádí omezené asynchronní I/O a vrací jeden výsledek; nemanipuluje ovládacími prvky z vlákna na pozadí. ShowResults a ShowCheckError jsou metody aplikace.
Normální pokračování await se vrací do kontextu UI, kde obslužná rutina začala, takže ShowResults může aktualizovat ovládací prvky. Kód explicitně běžící v jiném vlákně musí předávat přístup k ovládacím prvkům podporovaným mechanismem WinForms.
Seznam bezplatných proxy může poskytnout vstupní adresy; předávejte pouze protokoly implementované CheckProxyAsync. Osm je příklad rozpočtu. Další dávka čeká na nejpomalejší kontrolu v aktuální dávce a vyměňuje část propustnosti za omezené vytváření úloh. Uchovávejte termíny každé kontroly a zrušení v CheckProxyAsync; čekání na dávku nemůže dokončit neomezenou síťovou operaci.