The Chromium Chronicle #1: أفضل ممارسات جدولة المهام

يفخر فريق Chrome بتقديم Chromium Chronicle، وهو إصدار شهري مخصصة لمطوّري برامج Chromium، ومطوّري البرامج الذين أنشأوا المتصفح.

ستركّز خدمة Chromium Chronicle بشكل أساسي على نشر المعرفة التقنية. وأفضل الممارسات لكتابة وإنشاء واختبار Chrome. تتمثل خطتنا في عرض مواضيع ذات صلة ومفيدة لمطوّري برامج Chromium، مثل الرموز البرمجية الصحة والأدوات المفيدة واختبار الوحدة وإمكانية الوصول والمزيد! كل مقالة ستتم كتابتها وتعديلها من قِبل مهندسي Chrome.

نحن متحمسون بشأن هذه السلسلة الجديدة، ونأمل أن تكون أنت أيضًا كذلك. هل أنت مستعد لخوض التجربة؟ يمكنك إلقاء نظرة على الحلقة الأولى أدناه.

أفضل ممارسات جدولة المهام

الحلقة 1: من تأليف "غابرييل شاريت" في مونتريال، كولورادو (نيسان/أبريل 2019)
الحلقات السابقة

رمز Chrome الذي يحتاج إلى تنفيذ غير متزامن أثناء المعالجة ينشر عادةً المهام إلى التسلسلات. التسلسلات هي "سلاسل محادثات افتراضية" مُدارة من خلال Chrome. وهم تفضيل إنشاء سلسلة محادثات خاصة بك. كيف يعمل الكائن أي تسلسل ينبغي النشر فيه؟

الإجراءات غير المُوصى بها

النموذج القديم هو الحصول على SequencedTaskRunner من صانع المحتوى:

Foo::Foo(scoped_refptr backend_task_runner)
    : backend_task_runner_(std::move(backend_task_runner)) {}
الإجراءات الموصى بها

النموذج المفضل هو إنشاء SequencedTaskRunner مستقل:

Foo::Foo()
    : backend_task_runner_(
          base::CreateSequencedTaskRunnerWithTraits({
              base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {}

هذا من السهل القراءة والكتابة لأن جميع المعلومات محلية وهناك عدم وجود خطر الارتباط المتبادل مع المهام غير ذات الصلة.

هذا النموذج أفضل أيضًا عندما يتعلق الأمر بالاختبار. بدلاً من حقن بتشغيل المهام يدويًا، يمكن للاختبارات إنشاء بيئة مهام خاضعة للرقابة لإدارة مهام Foo:

class FooTest : public testing::Test {
 public
  (...)
 protected:
  base::test::TaskEnvironment task_environment_;
  Foo foo_;
};

إنّ توفير TaskEnvironment في المقام الأول في المرحلة يضمن ذلك بشكل طبيعي ويدير بيئة المهمة طوال عمر Foo. بيئة TaskEnvironment سيلتقط طلب Foo عند الإنشاء لإنشاء SequencedTaskRunner مهامه ضمن كل FooTest.

لاختبار نتيجة التنفيذ غير المتزامن، استخدم النموذج RunLoop::Run()+QuitClosure():

TEST_F(FooTest, TestAsyncWork) {
  RunLoop run_loop;
  foo_.BeginAsyncWork(run_loop.QuitClosure());
  run_loop.Run();
  EXPECT_TRUE(foo_.work_done());
}

يُفضَّل أن يكون هذا الخيار هو الخيار المفضّل "RunUntilIdle()"، والتي يمكن أن تكون غير مستقرة إذا كانت البيانات غير متزامنة عبء العمل تتضمن مهمة خارج نطاق اختصاص TaskEnvironment، مثلاً: حدث في النظام، لذا استخدِم RunUntilIdle() بحرص.

هل تريد الحصول على مزيد من المعلومات؟ الاطّلاع على مستنداتنا حول سلسلة المحادثات والمهام أو المشاركة في نقل البيانات إلى TaskEnvironment.