Smetti di bloccare WinForms mentre i controlli proxy sono in esecuzione
Sostituisci il Task.WaitAll sincrono nel gestore di eventi dell'interfaccia con batch limitati attesi, quindi aggiorna i controlli nel contesto UI ripreso.
Task.WaitAll in un gestore di clic WinForms blocca la finestra anche quando i controlli stessi usano HTTP asincrono. Il thread UI non può elaborare messaggi e le continuazioni catturate potrebbero richiedere lo stesso thread bloccato.
In .NET 6 o versione successiva, attendi invece un batch limitato:
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;
}
}Questo va in un form esistente con System.Linq e System.Threading.Tasks disponibili. CheckProxyAsync esegue I/O asincrono limitato e restituisce un risultato; non manipola i controlli da un thread in background. ShowResults e ShowCheckError sono metodi dell'applicazione.
La continuazione normale di await torna al contesto UI in cui è iniziato il gestore, quindi ShowResults può aggiornare i controlli. Il codice esplicitamente in esecuzione su un altro thread deve marshallare l'accesso ai controlli tramite il meccanismo WinForms supportato.
La lista di proxy gratuiti può fornire indirizzi di input; passa solo i protocolli implementati da CheckProxyAsync. Otto è un budget di esempio. Il batch successivo attende il controllo più lento del batch corrente, scambiando parte della velocità con una creazione di attività limitata. Mantieni le scadenze di ogni controllo e l'annullamento dentro CheckProxyAsync; attendere un batch non può far terminare un'operazione di rete illimitata.