Async و Await في لغة C#: كيف ومتى تستخدم (دليل تعليمي خطوة بخطوة)

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

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

ابدأ الدورة

Async و Await في لغة C#: إنقاذ التطبيق من "التجميد"

\n\n

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

\n\n

حل هذه المشكلة هو البرمجة غير المتزامنة. وفي لغة C#، الأدوات الرئيسية لذلك هي الكلمات المفتاحية async و await. إذا كنت قد تساءلت يومًا: "كيف ومتى تستخدم async و await؟" - فقد وصلت إلى المكان الصحيح. في هذا الدليل التعليمي، سنشرح كل شيء من الأساسيات إلى أفضل الممارسات، حتى تتمكن من كتابة كود سريع وسريع الاستجابة وقابل للتوسع.

\n\n

هذه المادة مبنية على سؤال شائع حقيقي من Stack Overflow، حصل على آلاف المشاهدات. قمنا بتكييفه لمحتوى تعليمي، مع إضافة أمثلة على الكود وشروحات واضحة.

\n\n

ما هما async و await؟ بكلمات بسيطة

\n\n

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

\n\n

عدم التزامن هو عندما تضع الحساء ليغلي (async) وبدون انتظار، تبدأ في تقطيع السلطة، وترتيب الطاولة، والقيام بأمور أخرى. عندما يصبح الحساء جاهزًا، تعود إليه (await). أنت لا تضيع الوقت - أنت فعال.

\n\n
    \n
  • async - معدّل للطريقة يخبر المترجم: "هذه الطريقة تحتوي على عمليات غير متزامنة. لا تحجب التيار عندما أواجه await".
  • \n
  • await - عامل يتم تطبيقه على مهمة (Task). يقول: "أوقف تنفيذ هذه الطريقة مؤقتًا حتى تكتمل المهمة، لكن لا تحجب التيار. بمجرد اكتمال المهمة، استمر في التنفيذ من هذه النقطة".
  • \n
\n\n

هام: await لا يحجب التيار. إنه يعيد التحكم إلى الكود المستدعي، ويستمر التيار في أداء عمل آخر.

\n\n

متى تستخدم async و await؟

\n\n

هذا هو السؤال الأكثر شيوعًا. الإجابة بسيطة: دائمًا عندما تقوم بعملية قد تستغرق وقتًا طويلاً (عمليات مرتبطة بالإدخال/الإخراج I/O-bound)، ولا تريد حجب التيار.

\n\n

إليك السيناريوهات النموذجية:

\n
    \n
  • طلبات الشبكة: استدعاءات HTTP (HttpClient)، العمل مع WebSocket.
  • \n
  • العمل مع الملفات: قراءة/كتابة ملفات كبيرة، العمل مع التدفقات.
  • \n
  • استعلامات قواعد البيانات: Entity Framework، ADO.NET، Dapper.
  • \n
  • العمل مع خدمات الويب: WCF، REST API.
  • \n
  • أي عمليات إدخال/إخراج (I/O): الوصول إلى القرص، الشبكة، الطابعة.
  • \n
\n\n

متى لا يجب استخدام async و await؟

\n
    \n
  • العمليات المرتبطة بوحدة المعالجة المركزية (CPU-bound): إذا كانت مهمتك تتطلب حسابات مكثفة (عرض ثلاثي الأبعاد، معالجة فيديو، حسابات رياضية معقدة)، فإن async/await لن يساعد. هنا يجب استخدام Task.Run أو Parallel للتوازي على عدة أنوية للمعالج.
  • \n
  • في منشئات الفئات (Constructors): لا يمكن أن تكون المنشئات غير متزامنة. استخدم طرق المصنع (public static async Task<MyClass> CreateAsync()).
  • \n
  • في دوال الحصول/تعيين الخصائص (Getters/Setters): هي أيضًا لا يمكن أن تكون غير متزامنة. استخدم الطرق.
  • \n
\n\n

كيف يعمل هذا؟ تحليل مع مثال على الكود

\n\n

دعنا نلقي نظرة على كود حقيقي. تخيل أننا نقوم بتحميل بيانات من خادم بعيد.

\n\n

مثال سيء (متزامن)

\n
public string GetDataFromWeb()\n{\n    usi                

المدونات

توصيات الكتب