Tôi muốn làm rõ câu trả lời của BJ Myers (đúng).
Trong C# một sự kiện có thể được coi như một trường kiểu đại biểu - giống như một thuộc tính có thể được coi là trường thuộc loại thuộc tính - và giá trị của trường đó có thể là rỗng. Nếu bạn ở trong tình huống không may có một trình xử lý sự kiện đang được sửa đổi trên một chuỗi trong khi một chuỗi khác đang cố gọi nó, bạn có thể vào tình huống:
if (this.SomeEvent != null)
this.SomeEvent(...);
không an toàn. Giá trị có thể được biến đổi để nó không phải là null trước khi kiểm tra, null sau khi kiểm tra, và chương trình bị treo.
Cách thông thường để tạo "chủ đề an toàn" này và tôi sử dụng cụm từ được khuyên dùng, là sao chép giá trị vào một địa phương và sau đó kiểm tra giá trị cục bộ cho giá trị rỗng. Điều này có lợi ích của việc không bị đổ vỡ với một dereference null. Tuy nhiên, các nhà phát triển thông minh sẽ lưu ý rằng vẫn còn một cuộc đua!Chuỗi có thể
- Non-null xử lý sự kiện được lưu trữ trên thread
- Event handler thiết lập để null trên thread B
- Nhà nước cần thiết cho xử lý sự kiện bị hủy diệt trên thread B
- Event handler chạy trên chủ đề A và chết khủng khiếp
Vì vậy, theo nghĩa đó, mẫu này không phải là "an toàn chủ đề". Nếu bạn đang ở vị trí không may này bạn chịu trách nhiệm đảm bảo rằng logic luồng thích hợp được triển khai để điều này không thể xảy ra. Bạn có thể làm điều đó tuy nhiên bạn muốn. Nếu bạn muốn các lợi ích (có thể nghi ngờ) có thể gọi trình xử lý sự kiện trên một chuỗi trong khi thay đổi sự kiện trên một chuỗi khác, thì bạn phải trả tiền để đảm bảo an toàn hoặc xử lý lỗi điều kiện chủng tộc.
Cá nhân tôi sẽ tránh tình trạng này như bệnh dịch hạch, nhưng tôi không đủ thông minh để viết mã đa luồng chính xác.
Bây giờ, đối với câu hỏi thực tế:
some_expression ?. ToString();
cũng giống như
temp = some_expression
temp == null ? null : temp.ToString()
Là mã sau "thread" theo ý kiến của bạn?
Nguồn
2016-03-04 01:37:06
Xin lỗi, nhưng khối mã đầu tiên của bạn có thể hoàn toàn an toàn, tùy thuộc vào ngữ cảnh mà nó được sử dụng và phạm vi của các biến liên quan. –
@KenWhite - Tôi nghĩ ý tưởng với khối đầu tiên là một luồng khác có thể đặt biến thành 'null' sau khi kiểm tra nhưng trước' .ToString() 'làm cho mã không thành công. Tôi sẽ nói rằng nó không phải là thread-safe. – Enigmativity
@Enigmativity: Các poster đặc biệt nói rằng khối mã là ** không an toàn thread **, mà không phải là một tuyên bố chính xác mà không biết bối cảnh hoặc phạm vi. Tôi chỉ ra rằng tuyên bố là không chính xác - nó không đúng sự thật rằng mã trong khối đó dứt khoát không phải là luồng an toàn. –