أساسيات المرونة: إعادة المحاولة والتراجع التدريجي
نفّذ عمليات إعادة محاولة بسيطة مع تراجع أسي وعشوائية؛ وميّز الأخطاء المؤقتة من القاتلة؛ وحدد أقصى للتأخير؛ وأوقف التنفيذ عند الإلغاء.
أساسيات المرونة: إعادة المحاولة والتراجع التدريجي درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 3 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 3 دروس في المجموع.
لماذا إعادة المحاولة والتراجع التدريجي
الهدف: جعل الاستدعاءات أكثر تحمّلًا للأخطاء.
- إعادة محاولة حالات الفشل المؤقتة
- استخدام التراجع الأسي مع jitter
- تحديد الحد الأقصى للمحاولات والحد الأقصى للتأخير
- التوقف عند الأخطاء القاتلة أو الإلغاء
تصنيف حالات الفشل
المؤقتة: حالات انتهاء المهلة، وأخطاء 429/5xx، والاضطرابات المؤقتة في الشبكة.
القاتلة: الطلبات غير الصحيحة، وعدم التفويض، وأخطاء التحقق—لا تُعِد المحاولة.
القاعدة: أعد المحاولة فقط فيما يمكن أن ينجح لاحقًا.
مساعد التراجع التدريجي
يزيد مساعد صغير مدة التأخير مع كل محاولة، ويضيف قدرًا صغيرًا من jitter؛ كما يضع حدًا أقصى للتأخير.
using System;
using System.Threading;
using System.Threading.Tasks;
public static class Backoff
{
// Compute delay = min(base * 2^attempt, cap) + jitter
public static int ComputeDelayMs(int attempt, int baseMs, int capMs, int jitterMs, Random rng)
{
long exp = (long)baseMs << attempt; // base * 2^attempt
if (exp > capMs) exp = capMs;
int jitter = rng.Next(0, jitterMs + 1); // [0..jitterMs]
return (int)exp + jitter;
}
}
public class Program
{
public static void Main(string[] args)
{
Random rng = new Random(123);
for (int i = 0; i < 5; i++)
{
int d = Backoff.ComputeDelayMs(i, 100, 2000, 50, rng);
Console.WriteLine("Attempt " + i + " -> " + d + " ms");
}
}
}
غلاف إعادة المحاولة
غلّف الاستدعاء: أعد المحاولة عند الاستثناءات المؤقتة فقط، وتوقف عند غيرها. وتنتظر كل إعادة محاولة مدة أطول مع إضافة jitter.
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static readonly Random Rng = new Random();
// Simulate an operation that sometimes fails transiently.
static async Task<string> FlakyAsync()
{
await Task.Delay(60);
// 50% chance of transient failure
if (DateTime.UtcNow.Ticks % 2 == 0) throw new TimeoutException("Transient");
return "OK";
}
static async Task<T> RetryAsync<T>(Func<Task<T>> action, int maxAttempts)
{
int baseMs = 100, capMs = 2000, jitterMs = 50;
for (int attempt = 0; attempt < maxAttempts; attempt++)
{
try
{
return await action();
}
catch (TimeoutException)
{
if (attempt == maxAttempts - 1) throw; // out of retries
int delay = Backoff.ComputeDelayMs(attempt, baseMs, capMs, jitterMs, Rng);
await Task.Delay(delay);
}
catch (Exception)
{
// Non-transient (unknown) -> do not retry
throw;
}
}
throw new InvalidOperationException("Unreachable");
}
public static void Main(string[] args)
{
try
{
string s = RetryAsync(FlakyAsync, 5).GetAwaiter().GetResult();
Console.WriteLine("Result: " + s);
}
catch (Exception ex)
{
Console.WriteLine("Failed: " + ex.GetType().Name);
}
}
}
إعادة المحاولة ضمن ميزانية
أضف ميزانية عامة باستخدام الإلغاء: مرّر الرموز إلى العملية وإلى فترات تأخير التراجع التدريجي معًا.
using System;
using System.Threading;
using System.Threading.Tasks;
public static class RetryUtil
{
static readonly Random Rng = new Random();
public static async Task<T> RetryAsync<T>(Func<CancellationToken, Task<T>> action, int maxAttempts, CancellationToken ct)
{
int baseMs = 100, capMs = 1500, jitterMs = 50;
for (int attempt = 0; attempt < maxAttempts; attempt++)
{
ct.ThrowIfCancellationRequested();
try
{
return await action(ct);
}
catch (TimeoutException)
{
if (attempt == maxAttempts - 1) throw;
int delay = Backoff.ComputeDelayMs(attempt, baseMs, capMs, jitterMs, Rng);
await Task.Delay(delay, ct); // pass token so we can abort waiting
}
}
throw new InvalidOperationException("Unreachable");
}
}
public class Program
{
static async Task<string> SometimesSlowAsync(CancellationToken ct)
{
await Task.Delay(200, ct);
if (DateTime.UtcNow.Millisecond % 3 != 0) throw new TimeoutException("Transient");
return "OK";
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(800); // overall budget
try
{
string s = RetryUtil.RetryAsync(SometimesSlowAsync, 5, cts.Token).GetAwaiter().GetResult();
Console.WriteLine("Done: " + s);
}
catch (OperationCanceledException) { Console.WriteLine("Canceled"); }
catch (Exception ex) { Console.WriteLine("Failed: " + ex.Message); }
}
}
إرشادات
نصائح:
- أعد محاولة الاستدعاءات idempotent فقط.
- ضع حدودًا قصوى لعدد المحاولات ومدة التأخير.
- أضف قدرًا صغيرًا من jitter لتجنب اندفاع أعداد كبيرة من الطلبات في الوقت نفسه.
- سجّل الفشل النهائي مع سببه وعدد المحاولات.
تعريف التراجع التدريجي
مراجعة
مراجعة: أعد محاولة الأخطاء المؤقتة فقط، وزِد فترات التأخير أسيًا مع وضع حد أقصى، وأضف jitter، وتوقف عند الإلغاء أو الأخطاء القاتلة.
الأسئلة الشائعة
هل درس «أساسيات المرونة: إعادة المحاولة والتراجع التدريجي» مجاني؟
نعم — نص درس «أساسيات المرونة: إعادة المحاولة والتراجع التدريجي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 3 دروس في المجموع.
ماذا ستتعلم في «أساسيات المرونة: إعادة المحاولة والتراجع التدريجي»؟
نفّذ عمليات إعادة محاولة بسيطة مع تراجع أسي وعشوائية؛ وميّز الأخطاء المؤقتة من القاتلة؛ وحدد أقصى للتأخير؛ وأوقف التنفيذ عند الإلغاء. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 3.
كم من الوقت يستغرق درس «أساسيات المرونة: إعادة المحاولة والتراجع التدريجي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أنماط CancellationToken والإلغاء التعاوني
- المهل الزمنية وIProgress والتخلص غير المتزامن (محاكاة)
- أساسيات المرونة: إعادة المحاولة والتراجع التدريجي