البرمجة غير المتزامنة في C#: دليل شامل للمبتدئين

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

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

ابدأ الدورة

البرمجة غير المتزامنة في C#: دليل شامل للمبتدئين

\n\n

البرمجة غير المتزامنة هي أحد المفاهيم الأساسية في التطوير الحديث باستخدام C#. فهي تتيح لتطبيقاتك البقاء مستجيبة دون حظر تيار التنفيذ أثناء العمليات الطويلة: قراءة الملفات، استعلامات قاعدة البيانات، أو استدعاءات HTTP. في هذا الدليل، سنشرح أساسيات التزامن غير المتزامن في C# مع أمثلة عملية.

\n\n

ما هي البرمجة غير المتزامنة ولماذا نحتاجها؟

\n\n

في البرمجة المتزامنة، يتم تنفيذ الكود بشكل تسلسلي. إذا قمت باستدعاء طريقة تنتظر ردًا من الخادم لمدة 5 ثوانٍ، فإن التيار بأكمله (واجهة المستخدم أو تيار العمل) يتجمد. يتوقف التطبيق عن الاستجابة. تحل البرمجة غير المتزامنة هذه المشكلة: بدلاً من حظر التيار، تعيد الطريقة التحكم إلى الكود المستدعي، وعندما تكون النتيجة جاهزة، تقوم بإخطاره بذلك.

\n\n

المزايا الرئيسية للتزامن غير المتزامن:

\n
    \n
  • استجابة واجهة المستخدم — لا تتجمد الواجهة أثناء العمليات الطويلة.
  • \n
  • قابلية التوسع — يمكن لتطبيقات الخادم معالجة المزيد من الطلبات دون إنشاء تيارات جديدة.
  • \n
  • الكفاءة — تُستخدم التيارات المحررة لمهام أخرى.
  • \n
\n\n

أساسيات async/await في C#

\n\n

الكلمتان المفتاحيتان async و await هما أساس البرمجة غير المتزامنة في C#. ظهرتا في C# 5.0 وجعلتا الكود غير المتزامن بسيطًا تقريبًا مثل الكود المتزامن.

\n\n

قواعد الاستخدام:

\n
    \n
  • يتم تمييز الطريقة بالكلمة المفتاحية async.
  • \n
  • يجب أن يكون نوع الإرجاع Task أو Task<T> أو void (فقط لمعالجات الأحداث).
  • \n
  • داخل الطريقة، استدعِ طرقًا غير متزامنة أخرى باستخدام الكلمة المفتاحية await.
  • \n
\n\n

مثال بسيط:

\n
using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\nclass Program\n{\n    static async Task Main(string[] args)\n    {\n        Console.WriteLine("نبدأ التحميل...");\n        string content = await DownloadWebPageAsync("https://example.com");\n        Console.WriteLine($"تم تحميل {content.Length} حرفًا");\n    }\n\n    static async Task<string> DownloadWebPageAsync(string url)\n    {\n        using HttpClient client = new HttpClient();\n        string result = await client.GetStringAsync(url);\n        return result;\n    }\n}
\n\n

لاحظ أن الطريقة Main مميزة أيضًا بـ async Task — وهذا مسموح به بدءًا من C# 7.1.

\n\n

الأنواع Task و Task<T> و ValueTask

\n\n

في البرمجة غير المتزامنة في C#، تُستخدم ثلاثة أنواع رئيسية لقيم الإرجاع:

\n\n
    \n
  • Task — للطرق التي لا تُرجع قيمة (مشابه لـ void).
  • \n
  • Task<T> — للطرق التي تُرجع قيمة من النوع T.
  • \n
  • ValueTask<T> — نسخة محسّنة للسيناريوهات التي تكون فيها النتيجة متاحة بشكل متزامن غالبًا (مثل من ذاكرة التخزين المؤقت).
  • \n
\n\n

مثال مع Task<T>:

\n
static async Task<int> CalculateSumAsync(int a, int b)\n{\n    await Task.Delay(1000); // محاكاة عمل طويل\n    return a + b;\n}\n\n// الاستدعاء:\nint result = await CalculateSumAsync(5, 3);\nConsole.WriteLine(result); // 8
\n\n

معالجة الأخطاء في الطرق غير المتزامنة

\n\n

يتم معالجة الاستثناءات في الطرق غير المتزامنة باستخدام كتلة try-catch القياسية. ومع ذلك، هناك فارق مهم: يتم حفظ الاستثناء في كائن Task ويتم "إلقاؤه" مرة أخرى عند استخدام await.

\n\n
static async Task<string> ReadFileAsync(string path)\n{\n    try\n    {\n        string content = await File.ReadAllTextAsync(path);\n        return content;\n    }\n    catch (FileNotFoundException ex)\n    {\n        Console.WriteLine($"الملف غير موجود: {ex.Message}");                

المدونات

توصيات الكتب