Task.WaitAll در یک کنترل‌کننده کلیک WinForms پنجره را مسدود می‌کند، حتی وقتی خود بررسی‌ها از HTTP ناهمگام استفاده می‌کنند. رشته رابط کاربری نمی‌تواند پیام‌ها را پردازش کند و ادامه‌های ثبت‌شده ممکن است به همان رشته مسدود نیاز داشته باشند.

در .NET 6 یا بالاتر، به‌جای آن منتظر یک دسته محدود بمانید:

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

این به یک فرم موجود با دسترس‌پذیری System.Linq و System.Threading.Tasks تعلق دارد. CheckProxyAsync ورودی/خروجی ناهمگام محدود انجام می‌دهد و یک نتیجه برمی‌گرداند؛ از رشته پس‌زمینه کنترل‌ها را دستکاری نمی‌کند. ShowResults و ShowCheckError متدهای برنامه هستند.

ادامه معمول await به بافت رابط کاربری که کنترل‌کننده در آن آغاز شد بازمی‌گردد، بنابراین ShowResults می‌تواند کنترل‌ها را به‌روزرسانی کند. کدی که صریحاً در رشته دیگری اجرا می‌شود باید دسترسی به کنترل‌ها را از طریق سازوکار پشتیبانی‌شده WinForms منتقل کند.

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

مقالات مرتبط