دکمه لغو باید اجرا را متوقف کند. اگر هر بررسی پروکسی لغو را بگیرد و به‌طور عادی برگردد، حلقه بیرونی به‌سادگی به پروکسی بعدی می‌رود. آن‌وقت صفحه طوری به نظر می‌رسد که گویی لغو هیچ کاری نکرده است.

در WinForms مدرن .NET، یک منبع را به‌عنوان فیلد فرم نگه دارید و بگذارید لغو به گرداننده رویداد برسد:

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های پروکسی است که برنامه از قبل تجزیه کرده است. ردیف‌هایی از فهرست پروکسی رایگان می‌توانند بررسی مجاز یک هدف عمومی را تغذیه کنند؛ پروتکل را حفظ کنید و فقط از انواعی استفاده کنید که این گرداننده پشتیبانی می‌کند. رابط کاربری منتظر هر عملیات می‌ماند، بنابراین حلقه پیام برای دریافت کلیک لغو آزاد می‌ماند.

توکن را به شبکه ببرید

بررسی جداگانه باید آن توکن را بپذیرد. یک بررسی 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 متعلق به بررسی‌کننده موجود هستند. برای این نقطه پایانی حد مناسب اندازه پاسخ و مهلت نگه دارید. بررسی‌کننده تولیدی می‌تواند کلاینت‌ها را بر اساس مسیر دوباره استفاده کند؛ قطعه نشان می‌دهد لغو کجا سفر می‌کند، نه طراحی مخزن اتصال.

اگر پروکسی‌های ناموفق باید ثبت و رد شوند، خطاهای شبکه مورد انتظار را پیرامون بررسی جداگانه بگیرید. بگذارید لغو اجرا به گرداننده بیرونی برسد. برای بررسی‌های موازی، توکن اجرا را با هر کارگر به اشتراک بگذارید و پیش از فعال کردن اجرای دیگر منتظر تکمیل آن‌ها بمانید.

مقالات مرتبط