Butang Batal harus menghentikan jalan. Jika setiap pemeriksaan proksi menangkap pembatalan dan kembali seperti biasa, gelung luar hanya beralih ke proksi seterusnya. Skrin kemudian kelihatan seolah-olah Batal tidak melakukan apa-apa.

Dalam .NET WinForms moden, kekalkan satu sumber sebagai medan borang dan biarkan pembatalan sampai ke pengendali peristiwa:

private CancellationTokenSource? activeRun;

private async void startButton_Click(object sender, EventArgs e)
{
    if (activeRun is not null) return;
    using var run = new CancellationTokenSource();
    activeRun = run;
    startButton.Enabled = false;
    try
    {
        foreach (Uri proxy in configuredProxies)
        {
            run.Token.ThrowIfCancellationRequested();
            await CheckProxyAsync(proxy, run.Token);
        }
        statusLabel.Text = "Finished";
    }
    catch (OperationCanceledException) when (run.IsCancellationRequested)
    {
        statusLabel.Text = "Stopped";
    }
    finally
    {
        activeRun = null;
        startButton.Enabled = true;
    }
}

private void cancelButton_Click(object sender, EventArgs e)
    => activeRun?.Cancel();

configuredProxies ialah senarai URI proksi yang sudah dihurai oleh aplikasi. Baris daripada senarai proksi percuma boleh memberi makan pemeriksaan sasaran awam yang dibenarkan; kekalkan protokol dan gunakan hanya jenis yang disokong pengendali ini. UI menunggu setiap operasi, jadi gelung mesej kekal bebas menerima klik batal.

Bawa token ke rangkaian

Pemeriksaan individu mesti menerima token itu. Pemeriksaan HTTP yang dipendekkan boleh kelihatan seperti ini:

private async Task CheckProxyAsync(Uri proxy, CancellationToken token)
{
    using var handler = new HttpClientHandler
    {
        Proxy = new System.Net.WebProxy(proxy),
        UseProxy = true
    };
    using var client = new HttpClient(handler);
    using var response = await client.GetAsync(
        probeUri, HttpCompletionOption.ResponseHeadersRead, token);
    response.EnsureSuccessStatusCode();
    string body = await response.Content.ReadAsStringAsync(token);
    RecordResult(proxy, body);
}

probeUri dan RecordResult milik pemeriksa sedia ada. Kekalkan had saiz respons yang sesuai dan tamat masa untuk titik akhir ini. Pemeriksa pengeluaran boleh menggunakan semula klien mengikut laluan; serpihan menunjukkan ke mana pembatalan bergerak, bukan reka bentuk kolam sambungan.

Jika proksi yang gagal perlu direkodkan dan dilangkau, tangkap kegagalan rangkaian yang dijangka di sekitar pemeriksaan individu. Biarkan pembatalan jalan terlepas ke pengendali luar. Untuk pemeriksaan selari, kongsi token jalan dengan setiap pekerja dan tunggu mereka selesai sebelum membolehkan jalan lain.

Artikel berkaitan