Το κουμπί Ακύρωση πρέπει να σταματά την εκτέλεση. Αν κάθε έλεγχος proxy πιάνει την ακύρωση και επιστρέφει κανονικά, ο εξωτερικός βρόχος απλώς προχωρά στον επόμενο proxy. Τότε η οθόνη δείχνει σαν να μην έκανε τίποτα η Ακύρωση.

Στο σύγχρονο .NET WinForms κρατήστε μία πηγή ως πεδίο φόρμας και αφήστε την ακύρωση να φτάσει στον χειριστή συμβάντος:

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 είναι η ήδη αναλυμένη λίστα URI proxy της εφαρμογής. Γραμμές από τη λίστα δωρεάν proxy μπορούν να τροφοδοτήσουν έναν επιτρεπόμενο έλεγχο δημόσιου στόχου· διατηρήστε το πρωτόκολλο και χρησιμοποιήστε μόνο τύπους που υποστηρίζει αυτός ο χειριστής. Το UI περιμένει κάθε λειτουργία, οπότε ο βρόχος μηνυμάτων μένει ελεύθερος να δεχτεί το κλικ ακύρωσης.

Μεταφέρετε το token στο δίκτυο

Ο μεμονωμένος έλεγχος πρέπει να δέχεται αυτό το token. Ένας συντομευμένος έλεγχος HTTP μπορεί να μοιάζει έτσι:

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 και RecordResult ανήκουν στον υπάρχοντα ελεγκτή. Κρατήστε ένα κατάλληλο όριο μεγέθους απόκρισης και ένα χρονικό όριο για αυτό το endpoint. Ένας ελεγκτής παραγωγής μπορεί να επαναχρησιμοποιεί clients ανά διαδρομή· το απόσπασμα δείχνει πού ταξιδεύει η ακύρωση, όχι σχεδιασμό pool συνδέσεων.

Αν οι αποτυχημένοι proxy πρέπει να καταγράφονται και να παραλείπονται, πιάστε αναμενόμενες αποτυχίες δικτύου γύρω από τον μεμονωμένο έλεγχο. Αφήστε την ακύρωση της εκτέλεσης να διαφύγει στον εξωτερικό χειριστή. Για παράλληλους ελέγχους, μοιραστείτε το token εκτέλεσης με κάθε εργάτη και περιμένετε την ολοκλήρωσή τους πριν ενεργοποιήσετε άλλη εκτέλεση.

Σχετικά άρθρα