Chronicle 1 של Chromium: שיטות מומלצות לתזמון משימות

צוות Chrome גאה להציג את Chromium Chronicle, מיועדת במיוחד למפתחי Chromium, מפתחים בדפדפן.

Chromium Chronicle יתמקד בעיקר בהפצת ידע טכני ושיטות מומלצות לכתיבה, פיתוח ובדיקה של Chrome. התוכנית שלנו היא להציג נושאים שרלוונטיים ושימושיים למפתחי Chromium, כמו קוד בריאות, כלים שימושיים, בדיקת יחידה, נגישות ועוד הרבה יותר! כל מאמר ייכתב ויערוך על ידי מהנדסי Chrome.

אנחנו מתרגשים מהסדרה החדשה הזו ומקווים שגם אתם. מוכנים להתחיל? כדאי לצפות בפרק הראשון בהמשך.

שיטות מומלצות לתזמון משימות

פרק 1: מאת Gabriel Charette במונטריאול, PQ (אפריל 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. סביבת המשימות יתעד את הבקשה-בבנייה של 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());
}

היא עדיפה על Runבינתיים(), אשר יכול להיות לא יציב אם עומס עבודה כולל משימה שלא במסגרת תפקידו של TaskEnvironment, לדוגמה אירוע במערכת, לכן חשוב להשתמש ב-RunUntilIdle() בזהירות.

רוצים עוד פרטים? כדאי לקרוא את התיעוד שלנו בנושא שרשורים ומשימות או להיות מעורבים בהעברה אל TaskEnvironment!