Chromium Chronicle #1: แนวทางปฏิบัติแนะนำสำหรับการกำหนดเวลางาน

ทีม Chrome ภูมิใจที่จะได้เปิดตัว Chromium Chronicle ซึ่งเป็นซีรีส์รายเดือนสำหรับ นักพัฒนาซอฟต์แวร์ Chromium ซึ่งเป็นนักพัฒนาซอฟต์แวร์ที่สร้างเบราว์เซอร์ขึ้นโดยเฉพาะ

Chromium Chronicle จะเน้นการเผยแพร่ความรู้ทางเทคนิคและแนวทางปฏิบัติแนะนำในการเขียน สร้าง และทดสอบ Chrome เป็นหลัก แผนของเราคือการนำเสนอหัวข้อที่เกี่ยวข้องและเป็นประโยชน์สำหรับนักพัฒนาซอฟต์แวร์ Chromium เช่น ประสิทธิภาพของโค้ด เครื่องมือที่มีประโยชน์ การทดสอบ 1 หน่วย การช่วยเหลือพิเศษ และอีกมากมาย! วิศวกร 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 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