Prestaňte blokovať WinForms, kým bežia kontroly proxy
Nahraďte synchronný Task.WaitAll v obsluhe udalosti UI očakávanými obmedzenými dávkami a potom aktualizujte ovládacie prvky v obnovenom kontexte UI.
Task.WaitAll v obsluhe kliknutia WinForms blokuje okno, aj keď samotné kontroly používajú asynchrónny HTTP. Vlákno UI nemôže spracúvať správy a zachytené pokračovania môžu potrebovať to isté zablokované vlákno.
V .NET 6 alebo novšom namiesto toho čakajte na obmedzenú 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;
}
}Toto patrí do existujúceho formulára s dostupnými System.Linq a System.Threading.Tasks. CheckProxyAsync vykonáva obmedzené asynchrónne vstupy a výstupy a vracia jeden výsledok; nemanipuluje s ovládacími prvkami z vlákna na pozadí. ShowResults a ShowCheckError sú metódy aplikácie.
Bežné pokračovanie await sa vracia do kontextu UI, kde obsluha začala, takže ShowResults môže aktualizovať ovládacie prvky. Kód, ktorý explicitne beží v inom vlákne, musí odovzdávať prístup k ovládacím prvkom cez podporovaný mechanizmus WinForms.
Zoznam bezplatných proxy môže poskytnúť vstupné adresy; odovzdávajte iba protokoly implementované v CheckProxyAsync. Osem je príklad rozpočtu. Ďalšia dávka čaká na najpomalšiu kontrolu v aktuálnej dávke a vymieňa časť priepustnosti za obmedzené vytváranie úloh. Zachovajte termíny každej kontroly a zrušenie v CheckProxyAsync; čakanie na dávku nemôže spôsobiť, že sa neobmedzená sieťová operácia dokončí.