Task.WaitAll WinForms paspaudimo apdorojime blokuoja langą net tada, kai patys tikrinimai naudoja asinchroninį HTTP. UI gija negali apdoroti pranešimų, o užfiksuotoms tęsinio dalims gali prireikti tos pačios užblokuotos gijos.

Naudojant .NET 6 ar naujesnę versiją, vietoj to laukite ribotos partijos:

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;
    }
}

Tai priklauso esamai formai, kurioje prieinami System.Linq ir System.Threading.Tasks. CheckProxyAsync atlieka ribotą asinchroninę įvestį ir išvestį ir grąžina vieną rezultatą; ji nevaldo valdiklių iš foninės gijos. ShowResults ir ShowCheckError yra programos metodai.

Įprastas await tęsinys grįžta į UI kontekstą, kuriame prasidėjo apdorojimas, todėl ShowResults gali atnaujinti valdiklius. Kodas, aiškiai vykdomas kitoje gijoje, turi perduoti valdiklių prieigą per palaikomą WinForms mechanizmą.

Nemokamų proxy sąrašas gali pateikti įvesties adresus; perduokite tik protokolus, kuriuos įgyvendina CheckProxyAsync. Aštuoni yra pavyzdinis biudžetas. Kita partija laukia lėčiausio dabartinės partijos tikrinimo, iškeisdama dalį pralaidumo į ribotą užduočių kūrimą. Laikykite kiekvieno tikrinimo terminus ir atšaukimą CheckProxyAsync viduje; laukimas partijos negali priversti neribotos tinklo operacijos baigtis.

Susiję straipsniai