المهل الزمنية وIProgress<T> والتخلص غير المتزامن (محاكاة)
طبّق المهل باستخدام CancelAfter أو Task.WhenAny، ووصل IProgress لتحديثات ملائمة للواجهة، واستخدم try/finally لمحاكاة التنظيف غير المتزامن في C# 6.
المهل الزمنية وIProgress<T> والتخلص غير المتزامن (محاكاة) درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 3 دروس في المجموع.
الخطة
الهدف:
- تعيين مهلة باستخدام CancelAfter
- تعيين مهلة باستخدام Task.WhenAny
- الإبلاغ عن التقدم باستخدام IProgress<T>
- استخدام نمط التنظيف غير المتزامن في C# 6 (try/finally)
مهلة باستخدام CancelAfter
استخدم CancelAfter ومرّر الرمز إلى واجهة برمجة التطبيقات غير المتزامنة؛ فتتوقف الدالة المستدعاة تعاونيًا عند انتهاء المهلة.
using System;
using System.Threading;
using System.Threading.Tasks;
public class Program
{
static async Task<string> SlowOpAsync(CancellationToken ct)
{
// Simulate slow I/O that honors cancellation
await Task.Delay(500, ct);
return "OK";
}
public static void Main(string[] args)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(150); // timeout after 150 ms
Task<string> t = SlowOpAsync(cts.Token);
try
{
string result = t.GetAwaiter().GetResult(); // demo only
Console.WriteLine(result);
}
catch (OperationCanceledException)
{
Console.WriteLine("Timed out");
}
}
}
مهلة باستخدام WhenAny
يجري Task.WhenAny سباقًا بين العمل وTask.Delay؛ وإذا فاز التأخير، فاطرح TimeoutException.
using System;
using System.Threading.Tasks;
public class Program
{
// Wrap any Task<T> with a timeout using WhenAny
static async Task<T> WithTimeoutAsync<T>(Task<T> work, int milliseconds)
{
Task delay = Task.Delay(milliseconds);
Task first = await Task.WhenAny(work, delay);
if (first == work) return await work; // completed in time
throw new TimeoutException("Operation timed out");
}
static async Task<int> ComputeAsync()
{
await Task.Delay(300); // pretend work
return 7;
}
public static void Main(string[] args)
{
try
{
int v = WithTimeoutAsync(ComputeAsync(), 100).GetAwaiter().GetResult();
Console.WriteLine("Value " + v);
}
catch (TimeoutException ex)
{
Console.WriteLine(ex.Message);
}
}
}
مثال على IProgress<T>
يفصل IProgress<T> العمل عن واجهة المستخدم؛ إذ تستدعي الجهات المنتجة Report، بينما تحدّث الجهات المستهلكة واجهة المستخدم أو خيط التنفيذ بأمان.
using System;
using System.Threading.Tasks;
public class Program
{
static async Task DownloadAsync(IProgress<int> progress)
{
// Report 0..100 in steps; UI would receive ProgressChanged on its context
for (int p = 0; p <= 100; p += 25)
{
await Task.Delay(60);
if (progress != null) progress.Report(p);
}
}
public static void Main(string[] args)
{
Progress<int> prog = new Progress<int>(percent =>
{
Console.WriteLine("Progress: " + percent + "%");
});
DownloadAsync(prog).GetAwaiter().GetResult();
}
}
نمط التنظيف غير المتزامن
لا يدعم C# 6 الواجهة IAsyncDisposable؛ لذا استخدم try/finally ونفّذ التخلص داخل finally بعد اكتمال العمل الذي تم انتظار نتيجته.
using System;
using System.IO;
using System.Threading.Tasks;
public class Program
{
static async Task WriteThenCloseAsync(string path)
{
// C# 6 has no IAsyncDisposable; emulate with try/finally.
FileStream fs = null;
StreamWriter sw = null;
try
{
fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
sw = new StreamWriter(fs);
await sw.WriteAsync("hello"); // do async work
await sw.FlushAsync(); // ensure data is flushed
}
finally
{
// Dispose synchronously in finally
if (sw != null) sw.Dispose();
else if (fs != null) fs.Dispose();
}
}
public static void Main(string[] args)
{
WriteThenCloseAsync("out.txt").GetAwaiter().GetResult();
Console.WriteLine("Written");
}
}
أفضل الممارسات
نصائح:
- فضّل CancelAfter لمهل العمليات البسيطة.
- استخدم WhenAny لتدفقات المهلة المخصصة.
- حافظ على صغر أنواع التقدم، مثل عدد صحيح للنسبة المئوية أو بنية بسيطة.
- أكمل دائمًا عمليات الانتظار قبل التخلص من الموارد؛ وضع عملية التخلص داخل finally.
نمط المهلة
مراجعة
مراجعة: نفّذ المهل باستخدام CancelAfter أو WhenAny، وأبلغ عن التقدم عبر IProgress<T>، وحاكِ التخلص غير المتزامن باستخدام try/finally في C# 6.
تعلم C# مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 93
- الدروس
- 346
الأسئلة الشائعة
هل درس «المهل الزمنية وIProgress<T> والتخلص غير المتزامن (محاكاة)» مجاني؟
نعم — نص درس «المهل الزمنية وIProgress<T> والتخلص غير المتزامن (محاكاة)» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 3 دروس في المجموع.
ماذا ستتعلم في «المهل الزمنية وIProgress<T> والتخلص غير المتزامن (محاكاة)»؟
طبّق المهل باستخدام CancelAfter أو Task.WhenAny، ووصل IProgress لتحديثات ملائمة للواجهة، واستخدم try/finally لمحاكاة التنظيف غير المتزامن في C# 6. تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟
لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.
كم من الوقت يستغرق درس «المهل الزمنية وIProgress<T> والتخلص غير المتزامن (محاكاة)»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟
نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أنماط CancellationToken والإلغاء التعاوني
- المهل الزمنية وIProgress والتخلص غير المتزامن (محاكاة)
- أساسيات المرونة: إعادة المحاولة والتراجع التدريجي