2010-01-15 38 views
16

Tôi phát hiện 'ThreadStaticAttribute', và tôi có rất nhiều câu hỏi về nó: tất cả các thông tin tĩnh phụ thuộc trước đây của tôi, được thực hiện như một từ điển tĩnh mà TKey là Thread, và khi tôi muốn truy cập nó, tôi đã sử dụng Thread. CurrentThread và hoạt động. Nhưng điều này đòi hỏi mantainance, bởi vì nếu một sợi chết, tôi phải xóa các mục tương ứng từ từ điển. Và tôi cũng cần xem xét an toàn luồng và nhiều vấn đề khác.C# ThreadStaticAttribute đánh dấu các lĩnh vực được tự động phát hành khi thread chết?

Bằng cách sử dụng ThreadStaticAttribute, tất cả những vấn đề này dường như được giải quyết, nhưng tôi cần phải chắc chắn về nó. Câu hỏi của tôi là: tôi cần phải xóa các trường hợp giữ bởi 'ThreadStaticAttribute' đánh dấu các lĩnh vực, bằng cách nào đó, trước khi chủ đề chết ?? Thông tin của trường đó giữ ở đâu ?? Đó là trong trường hợp của đối tượng Thread, hoặc một cái gì đó như thế, để khi nó không được sử dụng nữa, thu gom rác tự động loại bỏ nó? Có hình phạt về hiệu suất không? Cái gì? Nó có nhanh hơn việc sử dụng một bộ sưu tập có khóa như tôi đang làm không?

Xin vui lòng, tôi cần làm rõ về cách hoạt động của ThreadStaticAttribute.

Cảm ơn.

Trả lời

11

Không, bạn không cần phải xóa các trường hợp trợ giúp giá trị trong trường được gắn thẻ với ThreadStatic. Bộ thu gom rác sẽ tự động nhận chúng khi cả chủ đề và đối tượng không thể truy cập được bởi các đối tượng gốc.

Ngoại lệ duy nhất ở đây là nếu giá trị thực hiện IDisposable và bạn muốn chủ động vứt bỏ nó. Nói chung đây là một vấn đề khó giải quyết vì một số lý do. Nó đơn giản hơn nhiều khi không có giá trị thực hiện IDisposable và nằm trong trường ThreadStatic.

Đối với nơi mà trường dữ liệu này thực sự được lưu trữ, nó hơi không liên quan. Tất cả những gì bạn cần quan tâm là nó sẽ hoạt động giống như bất kỳ đối tượng nào khác trong .Net. Hai khác biệt hành vi duy nhất là

  1. Trường sẽ tham chiếu giá trị khác nhau cho mỗi chuỗi truy cập.
  2. Trình khởi tạo cho trường này sẽ chỉ chạy một lần (trong thực tế, đó là ý tưởng tồi để có bất kỳ).
6

Đánh dấu biến thành viên tĩnh là [ThreadStatic] yêu cầu trình biên dịch phân bổ nó trong vùng bộ nhớ của chủ đề (ví dụ: ngăn xếp của luồng) thay vì trong vùng bộ nhớ chung. Vì vậy, mỗi luồng sẽ có bản sao riêng của nó (được đảm bảo được khởi tạo thành giá trị mặc định cho kiểu đó, ví dụ: null, 0, false, v.v.) không sử dụng bộ khởi tạo nội dòng vì chúng sẽ chỉ khởi tạo nó cho một luồng).

Vì vậy, khi chuỗi đó biến mất, vùng nhớ của nó cũng vậy, giải phóng tham chiếu. Tất nhiên nếu đó là thứ cần xử lý ngay lập tức (mở luồng tệp, v.v.) thay vì đợi thu gom rác nền, bạn có thể muốn chắc chắn rằng bạn làm điều đó trước khi thoát khỏi chuỗi.

Có thể có giới hạn về số lượng không gian [ThreadStatic] có sẵn, nhưng nó phải đủ để sử dụng sane. Nó sẽ được phần nào nhanh hơn truy cập vào một bộ sưu tập có khóa (và dễ dàng hơn thread-an toàn), và tôi nghĩ rằng đó là so sánh để truy cập một biến tĩnh bình thường.

Hiệu chỉnh: Tôi đã nghe nói rằng việc truy cập các biến ThreadStatic hơi chậm hơn so với truy cập các biến tĩnh bình thường.Tôi không chắc liệu nó có thực sự nhanh hơn việc truy cập một bộ sưu tập có khóa hay không, nhưng nó tránh các vấn đề của trẻ mồ côi (đó là câu hỏi của bạn) và cần khóa cho an toàn mà sẽ làm phức tạp một phương pháp thu thập khóa.

+1

Trình biên dịch hoàn toàn nghĩa là không làm gì cho thuộc tính 'ThreadStatic'. Nó được xử lý hoàn toàn bởi CLR – JaredPar

+0

Được rồi, nhưng lấy "trình biên dịch" theo nghĩa ẩn dụ chứ không phải là nghĩa đen, bạn có ý tưởng về cách sử dụng thuộc tính. –

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