Chromium Chronicle #1: Các phương pháp hay nhất để lên lịch công việc

Nhóm Chrome tự hào giới thiệu Chromium Chronicle, một chuỗi sản phẩm hằng tháng dành riêng cho nhà phát triển Chromium, nhà phát triển xây dựng trình duyệt này.

Chromium Chronicle chủ yếu tập trung vào việc truyền bá kiến thức kỹ thuật và các phương pháp hay nhất để viết, xây dựng và kiểm thử Chrome. Kế hoạch của chúng tôi là làm nổi bật các chủ đề phù hợp và hữu ích cho nhà phát triển Chromium, chẳng hạn như trạng thái mã, các công cụ hữu ích, kiểm thử đơn vị, khả năng hỗ trợ tiếp cận và nhiều chủ đề khác! Mỗi bài viết sẽ do các kỹ sư Chrome viết và chỉnh sửa.

Chúng tôi rất hào hứng với loạt video mới này và hy vọng bạn cũng vậy! Bạn đã sẵn sàng tìm hiểu sâu hơn chưa? Hãy xem tập đầu tiên của chúng tôi ở bên dưới!

Các phương pháp hay nhất để lên lịch cho tác vụ

Tập 1: của Gabriel Charette ở Montréal, PQ (tháng 4 năm 2019)
Các tập trước

Mã Chrome cần thực thi không đồng bộ trong quá trình thường đăng các tác vụ vào trình tự. Trình tự là "luồng ảo" do Chrome quản lý và được ưu tiên tạo luồng của riêng bạn. Làm cách nào để một đối tượng biết cần đăng lên trình tự nào?

Không nên

Mô hình cũ là nhận SequencedTaskRunner từ nhà sáng tạo:

Foo::Foo(scoped_refptr backend_task_runner)
    : backend_task_runner_(std::move(backend_task_runner)) {}
Nên

Mô hình ưu tiên là tạo một SequencedTaskRunner độc lập:

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

Thao tác này sẽ dễ đọc và ghi hơn vì tất cả thông tin đều cục bộ, đồng thời không có nguy cơ phụ thuộc lẫn nhau với các tác vụ không liên quan.

Mô hình này cũng tốt hơn cho việc kiểm thử. Thay vì chèn trình chạy tác vụ theo cách thủ công, quy trình kiểm thử có thể tạo thực thể cho môi trường tác vụ có kiểm soát để quản lý các tác vụ của Foo:

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

Việc có TaskEnvironment (Môi trường tác vụ) được đưa vào môi trường cố định một cách tự nhiên sẽ đảm bảo việc này sẽ quản lý môi trường tác vụ trong suốt thời gian hoạt động của Foo. Môi trường tác vụ sẽ ghi lại quá trình tạo yêu cầu của Foo để tạo một SequencedTaskRunner và sẽ quản lý các nhiệm vụ của nó trong từng FooTest.

Để kiểm thử kết quả thực thi không đồng bộ, hãy sử dụng mô hình RunLoop::Run()+QuitClosure():

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

Phương thức này được ưu tiên đối với RununtilIdle(), phương thức này có thể không ổn định nếu khối lượng công việc không đồng bộ liên quan đến một tác vụ nằm ngoài mục đích của Môi trường tác vụ, chẳng hạn như một sự kiện hệ thống, vì vậy, hãy sử dụng RunUntilIdle() một cách cẩn thận.

Bạn muốn tìm hiểu thêm? Hãy đọc tài liệu của chúng tôi về luồng và tác vụ hoặc tham gia quá trình di chuyển sang Môi trường tác vụ!