Có rất nhiều câu hỏi ở đây. Xem xét chúng tại một thời điểm:
phép gán tham chiếu là nguyên tử, vậy tại sao lại cần Interlocked.Exchange (ref Object, Object)?
Phép gán tham chiếu là nguyên tử. Interlocked.Exchange không chỉ thực hiện việc gán tham chiếu. Nó thực hiện việc đọc giá trị hiện tại của một biến, xóa giá trị cũ và gán giá trị mới cho biến, tất cả đều như một phép toán nguyên tử.
đồng nghiệp của tôi nói rằng trên một số nền tảng, không đảm bảo rằng việc gán tham chiếu là nguyên tử. Đồng nghiệp của tôi có đúng không?
Không. Việc gán tham chiếu được đảm bảo là nguyên tử trên tất cả các nền tảng .NET.
Đồng nghiệp của tôi đang suy luận từ những tiền đề sai lầm. Điều đó có nghĩa là kết luận của họ không chính xác?
Không cần thiết. Đồng nghiệp của bạn có thể đưa ra lời khuyên tốt cho bạn vì những lý do xấu. Có lẽ có một số lý do khác khiến bạn nên sử dụng Interlocked.Exchange. Lập trình không có khóa cực kỳ khó khăn và thời điểm bạn rời khỏi các phương pháp thực hành đã được thiết lập tốt bởi các chuyên gia trong lĩnh vực này, bạn sẽ lạc lối và mạo hiểm với loại điều kiện chủng tộc tồi tệ nhất. Tôi không phải là chuyên gia trong lĩnh vực này và cũng không phải là chuyên gia về mã của bạn, vì vậy tôi không thể đưa ra nhận định theo cách này hay cách khác.
tạo ra cảnh báo "tham chiếu đến một trường dễ bay hơi sẽ không được coi là dễ bay hơi" Tôi nên nghĩ gì về điều này?
Bạn nên hiểu tại sao đây là một vấn đề nói chung. Điều đó sẽ dẫn đến sự hiểu biết về lý do tại sao cảnh báo không quan trọng trong trường hợp cụ thể này.
Lý do mà trình biên dịch đưa ra cảnh báo này là vì việc đánh dấu một trường là dễ bay hơi có nghĩa là "trường này sẽ được cập nhật trên nhiều luồng - không tạo bất kỳ mã nào lưu trữ các giá trị của trường này và đảm bảo rằng mọi lần đọc hoặc ghi trường này không được "chuyển tới và lùi theo thời gian" thông qua sự mâu thuẫn trong bộ nhớ cache của bộ xử lý. "
(Tôi cho rằng bạn đã hiểu tất cả những điều đó rồi. Nếu bạn không hiểu chi tiết về ý nghĩa của biến động và cách nó tác động đến ngữ nghĩa bộ nhớ đệm của bộ xử lý thì bạn không hiểu nó hoạt động như thế nào và không nên sử dụng dễ bay hơi. Các chương trình không khóa rất khó để đi đúng; hãy đảm bảo rằng chương trình của bạn đúng vì bạn hiểu cách hoạt động của nó, không phải do ngẫu nhiên mà có.)
Bây giờ, giả sử bạn tạo một biến là bí danh của trường biến động bằng cách chuyển một tham chiếu đến trường đó. Bên trong phương thức được gọi, trình biên dịch không có lý do gì để biết rằng tham chiếu cần phải có ngữ nghĩa dễ bay hơi! Trình biên dịch sẽ vui vẻ tạo mã cho phương thức không triển khai các quy tắc cho trường biến động, nhưng biến là một trường dễ bay hơi. Điều đó hoàn toàn có thể phá hỏng logic không có khóa của bạn; giả định luôn luôn là một trường biến động luôn được truy cập với ngữ nghĩa biến động. Sẽ chẳng có nghĩa lý gì khi coi nó là đôi khi dễ bay hơi chứ không phải lúc khác; bạn phải luôn nhất quán nếu không bạn không thể đảm bảo tính nhất quán trên các truy cập khác.
Do đó, trình biên dịch cảnh báo khi bạn làm điều này, vì nó có thể sẽ làm rối tung hoàn toàn logic không có khóa được phát triển cẩn thận của bạn.
Tất nhiên, Interlocked.Exchange được viết để mong đợi một trường biến động và làm điều đúng đắn. Cảnh báo do đó gây hiểu lầm. Tôi rất hối hận về điều này; những gì chúng ta nên làm là thực hiện một số cơ chế theo đó tác giả của một phương thức như Interlocked.Exchange có thể đặt một thuộc tính trên phương thức nói rằng "phương thức này có tham chiếu thực thi ngữ nghĩa dễ bay hơi trên biến, vì vậy hãy loại bỏ cảnh báo". Có lẽ trong một phiên bản tương lai của trình biên dịch, chúng tôi sẽ làm như vậy.