2017-03-22 16 views
7

Tôi đang làm việc trên một cơ sở mã rất lớn và cũ của ứng dụng biểu mẫu máy tính để bàn. Trong cơ sở mã này có rất nhiều hoạt động được thực hiện trong các chủ đề nền, chủ yếu là sử dụng BackgroundWorker.Hiệu ứng của AsyncLocal <T> trong mã không đồng bộ/chờ đợi là gì?

Một mẫu phổ biến trong cơ sở mã này, là để che giấu sự phức tạp bằng các tạo phẩm ràng buộc với chuỗi đang được thực hiện. Ví dụ, kết nối cơ sở dữ liệu và giao dịch được lưu trữ trong các trường [ThreadStatic].

Tôi đang cố thay đổi điều này và bắt đầu sử dụng mã async/await và hưởng lợi từ việc chạy tác vụ trong bất kỳ chủ đề nào của hồ bơi và cho phép tác vụ tiếp tục thực hiện trong bất kỳ chủ đề nào khác bằng cách sử dụng ConfigureAwait(false). Tôi biết rằng [ThreadStatic] không hoạt động tốt với async/await và tôi đã đọc một số câu trả lời ở đây đề xuất sử dụng AsyncLocal<T> thay thế.

Vì tôi đang làm việc trên một cơ sở mã lớn, như đã đề cập trước đây, tôi không thể chuyển sang async/await ở khắp mọi nơi trong một lần chụp và tôi phải thực hiện thay đổi dần dần. Vì vậy, mã trước đó có [ThreadStatic] sẽ thay đổi thành AsyncLocal<T>, nhưng phần lớn mã sẽ tiếp tục sử dụng BackgroundWorker và sẽ không trúng một dòng mã đơn lẻ async/await.

Câu hỏi
Điều này có hiệu quả không? Tôi cần có thể xác định một số loại luồng ngữ cảnh sẽ hoạt động với mã mới async/await của mình và tiếp tục làm việc với mã không đồng bộ cũ của tôi dựa trên số [ThreadStatic] giữ mọi công cụ chủ đề độc lập với nhau.

Nếu tôi hoàn toàn sai và đi sai đường dẫn, đề xuất rất được hoan nghênh.

Trả lời

7

Nó sẽ hoạt động.

AsyncLocal<T> là sự trừu tượng hóa ngữ cảnh cuộc gọi logic. Tôi mô tả chi tiết the logical call context and how it interacts with async/await trong một bài đăng blog cũ.

Tóm lại, nó có thể hoạt động tốt, nhưng có một khía cạnh là AsyncLocal<T> hoàn toàn khác với ThreadStatic.

Khi bạn viết tới giá trị AsyncLocal<T>, giá trị đó được đặt cho ngữ cảnh cuộc gọi logic hiện tại. Phương thức async sẽ thiết lập phạm vi copy-on-write cho ngữ cảnh cuộc gọi logic của nó, vì vậy nếu bạn viết vào trong phương thức an async, nó sẽ tạo một ngữ cảnh cuộc gọi logic mới có chứa giá trị mới. Điều này cho phép phương pháp async sử dụng phương thức này theo kiểu lồng nhau, trong đó ngữ cảnh "bên trong" có thể ghi đè ngữ cảnh "bên ngoài". Tuy nhiên, giá trị ngữ cảnh "bên trong" không bao giờ quay trở lại người gọi; khi bối cảnh "bên ngoài" được tiếp tục, nó hoàn toàn thay thế bối cảnh "bên trong".

Nếu không có phương pháp nào là async và giá trị chỉ được đặt từ chủ đề của riêng chúng, thì chuỗi đó chỉ có ngữ cảnh cuộc gọi logic và ghi/đọc các giá trị sẽ hoạt động giống như ThreadStatic.

Các vấn đề liên quan