سؤال

أعلنت Microsoft Visual Studio Async CTP اليوم (28 أكتوبر 2010) الذي يقدم async و await الكلمات الرئيسية في C#/VB لتنفيذ الطريقة غير المتزامنة.

أولاً ، اعتقدت أن المترجم يترجم الكلمات الرئيسية إلى إنشاء مؤشر ترابط ولكن وفقًا لـ ورق ابيض و Anders Hejlsberg's عرض PDC (في الساعة 31:00) تحدث العملية غير المتزامنة تمامًا على الخيط الرئيسي.

كيف يمكنني تنفيذ عملية بالتوازي مع نفس الخيط؟ كيف يمكن ذلك من الناحية الفنية وما هي الميزة المترجمة بالفعل في IL؟

هل كانت مفيدة؟

المحلول

يعمل بشكل مشابه ل yield return الكلمة الرئيسية في C# 2.0.

الطريقة غير المتزامنة ليست في الواقع طريقة متسلسلة عادية. يتم تجميعه في آلة الحالة (كائن) مع بعض الحالة (يتم تحويل المتغيرات المحلية إلى حقول للكائن). كل كتلة من الكود بين استخدامين await هي "خطوة" لآلة الحالة.

هذا يعني أنه عندما تبدأ الطريقة ، فإنها تدير الخطوة الأولى فقط ، ثم تقوم جهاز الحالة بإرجاع بعض الأعمال التي يتعين القيام بها - عند الانتهاء من العمل ، سيتم تشغيل الخطوة التالية من آلة الحالة. على سبيل المثال هذا الرمز:

async Task Demo() { 
  var v1 = foo();
  var v2 = await bar();
  more(v1, v2);
}

سوف تترجم إلى شيء مثل:

class _Demo {
  int _v1, _v2;
  int _state = 0; 
  Task<int> _await1;
  public void Step() {
    switch(this._state) {
    case 0: 
      this._v1 = foo();
      this._await1 = bar();
      // When the async operation completes, it will call this method
      this._state = 1;
      op.SetContinuation(Step);
    case 1:
      this._v2 = this._await1.Result; // Get the result of the operation
      more(this._v1, this._v2);
  }
}

الجزء المهم هو أنه يستخدم فقط SetContinuation طريقة لتحديد أنه عند اكتمال العملية ، يجب أن تستدعي Step الطريقة مرة أخرى (والطريقة تعرف أنه يجب تشغيل الجزء الثاني من الكود الأصلي باستخدام _state مجال). يمكنك بسهولة أن تتخيل أن SetContinuation سيكون شيئًا مثل btn.Click += Step, ، والتي من شأنها أن تعمل تماما على موضوع واحد.

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

الترجمة مشابهة للتكرار (و yield return) وفي الواقع ، كان من الممكن استخدام المتكررين لتنفيذ البرمجة غير المتزامنة في C# في وقت سابق. كتبت مقال عن ذلك منذ فترة - وأعتقد أنه لا يزال بإمكانك إعطائك بعض البصيرة حول كيفية عمل الترجمة.

نصائح أخرى

كيف يمكنني تنفيذ عملية بالتوازي مع نفس الخيط؟

لا يمكنك. عدم التزامن ليس "التوازي" أو "التزامن". قد يتم تنفيذ عدم التزامن بالتوازي ، أو قد لا يكون كذلك. قد يتم تنفيذه عن طريق تقسيم العمل إلى أجزاء صغيرة ، ووضع كل جزء من العمل في قائمة انتظار ، ثم تنفيذ كل جزء من العمل كلما صادف عدم القيام بأي شيء آخر.

لدي سلسلة كاملة من المقالات على مدونتي حول كيفية عمل كل هذه الأشياء ؛ من المحتمل أن يرتفع الشخص الذي يدور مباشرة في هذا السؤال يوم الخميس من الأسبوع المقبل. راقب

http://blogs.msdn.com/b/ericlippert/archive/tags/async/

للتفاصيل.

كما أفهمها ، ماذا async و await الكلمات الرئيسية تفعل أنه في كل مرة async الطريقة توظف await الكلمة الرئيسية ، سوف يحول المترجم باقي الطريقة إلى استمرار يتم جدولة عند اكتمال عملية ASYNC. ذلك يسمح async طرق العودة إلى المتصل على الفور واستئناف العمل عند الانتهاء من جزء Async.

وفقًا للأوراق المتاحة ، هناك الكثير من التفاصيل ، لكن ما لم أكن مخطئًا ، فهذه هي جوهرها.

كما أراها ، فإن الغرض من أساليب Async هو عدم تشغيل الكثير من التعليمات البرمجية بالتوازي ، ولكن لتقطيع طرق Async إلى عدد من القطع الصغيرة ، والتي يمكن استدعاؤها حسب الحاجة. النقطة الأساسية هي أن المترجم سيتعامل مع جميع الأسلاك المعقدة للاسترداد باستخدام المهام/الاستمرارية. هذا لا يقلل من التعقيد فحسب ، بل يسمح بكتابة طريقة Async إلى حد ما مثل التعليمات البرمجية التقليدية المتزامنة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top