Polly لـ C# (.NET): دليل شامل مع أمثلة عملية

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

ما هي مكتبة Polly ولماذا تحتاجها؟

Polly هي مكتبة قوية ومرنة لـ .NET (C#, F#, VB.NET) مصممة للتعامل مع الأعطال المؤقتة وزيادة تحمل الأخطاء في التطبيقات. تنفذ أنماط الثبات مثل إعادة المحاولة (Retry)، قاطع الدائرة (Circuit Breaker)، المهلة الزمنية (Timeout)، العزل (Bulkhead Isolation)، والتخزين المؤقت (Cache).

في عالم اليوم من البنية التحتية للخدمات المصغرة والحوسبة السحابية، تتفاعل التطبيقات باستمرار مع الموارد الخارجية: قواعد البيانات، خدمات الويب، واجهات API. هذه التفاعلات قد تكون غير موثوقة — أخطاء الشبكة، عدم توفر الخدمة مؤقتًا، تجاوز حدود الطلبات. تتيح لك Polly التعامل مع هذه المواقف بأناقة، دون كتابة كود ضخم باستخدام كتل try-catch.

حالات الاستخدام الرئيسية:

  • إعادة المحاولة (Retry): إعادة تنفيذ العملية تلقائيًا عند حدوث خطأ مؤقت.
  • قاطع الدائرة (Circuit Breaker): إيقاف محاولات الاتصال إذا كانت الخدمة ترجع أخطاء باستمرار، لإعطائها وقتًا للتعافي.
  • المهلة الزمنية (Timeout): تحديد وقت أقصى لتنفيذ العملية.
  • العزل (Bulkhead): الحد من عدد العمليات المتزامنة لمنع عملية "سيئة" من حظر مجموعة الخيوط بأكملها.
  • التخزين المؤقت (Cache): تخزين نتائج العمليات الناجحة مؤقتًا.
  • البديل (Fallback): تنفيذ إجراء بديل في حالة الفشل.

تثبيت Polly

يتم توزيع Polly عبر NuGet — مدير الحزم لـ .NET. يمكن تثبيتها بعدة طرق:

عبر Package Manager Console (Visual Studio)

Install-Package Polly

عبر .NET CLI

dotnet add package Polly

عبر PackageReference (في ملف .csproj)

<PackageReference Include="Polly" Version="8.2.0" />

بعد التثبيت، أضف توجيهات using إلى الكود الخاص بك:

using Polly;
using Polly.Retry;
using Polly.CircuitBreaker;
using Polly.Timeout;
using Polly.Bulkhead;
using Polly.Caching;
using Polly.Fallback;
using Polly.Wrap;

بداية سريعة مع مثال كود

لننظر إلى مثال بسيط: لدينا دالة تستدعي API خارجي، ونريد إعادة المحاولة 3 مرات في حالة حدوث استثناء.

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Polly;
using Polly.Retry;

public class ApiClient
{
    private readonly HttpClient _httpClient;
    private readonly AsyncRetryPolicy _retryPolicy;

    public ApiClient()
    {
        _httpClient = new HttpClient();
        
        // إنشاء سياسة إعادة المحاولة
        _retryPolicy = Policy
            .Handle<HttpRequestException>() // الاستثناءات التي نتعامل معها
            .Or<TimeoutException>()          // أو المهلة الزمنية
            .WaitAndRetryAsync(
                3,                           // عدد المحاولات
                retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // تأخير أسي
                onRetry: (exception, timeSpan, retryCount, context) =>
                {
                    Console.WriteLine($"المحاولة {retryCount} فشلت. إعادة المحاولة بعد {timeSpan.Seconds} ثانية. الخطأ: {exception.Message}");
                }
            );
    }

    public async Task<string> GetDataAsync(string url)
    {
        // تنفيذ الطلب باستخدام السياسة
        return await _retryPolicy.ExecuteAsync(async () =>
        {
            var response = await _httpClient.GetAsync(url);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        });
    }
}

// الاستخدام
public class Program
{
    public static async Task Main()
    {
        var client = new ApiClient();
        try
        {                    

توصيات