2013-08-16 23 views
8

Lấy đoạn mã sau, những gì xảy ra trong một môi trường đa luồng:là nó chủ đề an toàn để gán một giá trị mới cho một đối tượng tĩnh trong C#

static Dictionary<string,string> _events = new Dictionary<string,string>(); 

public static Dictionary<string,string> Events { get { return _events;} } 

public static void ResetDictionary() 
{ 
    _events = new Dictionary<string,string>(); 
} 

Trong một môi trường đa luồng phương pháp này và tài sản có thể được truy cập trong cùng một thời gian bởi các chủ đề khác nhau.

Chủ đề có an toàn khi gán một đối tượng mới cho biến tĩnh có thể truy cập được trong các chuỗi khác nhau không? Điều gì có thể xảy ra?

Có thời điểm nào khi Sự kiện có thể trống không? Nếu 2 chủ đề gọi cùng lúc với số EventsResetDictionary() chẳng hạn.

+1

Nếu hai chủ đề gọi 'Events' và' ResetDictionary' đồng thời, thì điều * có thể xảy ra là: Thread 1 thực hiện điều gì đó với 'Events' và' Events' là một từ điển trống, * * hoặc ** Thread 2 gọi 'ResetDictionary' trước và sau đó một cái gì đó được thực hiện với nó bằng Thread 2.' Events' sẽ không kết thúc bằng 'null' trừ khi nó được đặt thành' null' bởi một luồng khác; điều này có thể dẫn đến một ngoại lệ con trỏ null, khi một thread kiểm tra 'Events! = null' trước khi' ResetDictionary' được gọi bởi một cái khác. – Nolonar

+2

Sử dụng biến tĩnh mà bạn mong đợi giá trị biến không thay đổi (tương tự cho mỗi yêu cầu) hoặc thậm chí nếu thay đổi nó không ảnh hưởng đến ứng dụng của bạn (Tuy nhiên nó sẽ ảnh hưởng.), Có khả năng ứng dụng của bạn sẽ chạy sai logic và nó sẽ thậm chí không tăng bất kỳ ngoại lệ nào, hãy xem xét người dùng thay đổi bất kỳ giá trị nào và sau đó mọi yêu cầu đến khác xử lý dữ liệu sai cho đến khi giá trị được đặt lại bởi một số logic khác. Vì vậy, sử dụng các biến tĩnh một cách khôn ngoan. –

Trả lời

13

Chủ đề có an toàn khi gán một đối tượng mới cho biến tĩnh có thể truy cập được trong các chuỗi khác nhau không?

Về cơ bản, có. Theo nghĩa là tài sản sẽ không bao giờ không hợp lệ hoặc null.

Điều gì có thể xảy ra?

Chuỗi đọc có thể tiếp tục sử dụng từ điển cũ sau khi một chủ đề khác đã đặt lại. Điều này phụ thuộc hoàn toàn vào logic và yêu cầu của chương trình của bạn như thế nào.

0

nếu bạn muốn kiểm soát mọi thứ trong môi trường đa luồng, bạn phải sử dụng cờ có thể truy cập bởi tất cả các đầu và kiểm soát các phương pháp bạn sử dụng trên từ điển của mình!

// the dictionary 
static Dictionary<string, string> _events = new Dictionary<string, string>(); 

// public boolean 
static bool isIdle = true; 

// metod that a thread calls 
bool doSomthingToDictionary() 
{ 
    // if another thread is using this method do nothing, 
    // just return false. (the thread will get false and try another time!) 
    if (!isIdle) return false; 

    // if it is Idle then: 
    isIdle = false; 
    ResetDictionary(); // do anything to your dictionary here 
    isIdle = true; 
    return true; 
} 

một điều nữa! bạn có thể sử dụng phương thức Invoke để chắc chắn rằng khi một luồng đang thao tác một biến hoặc gọi một hàm trong một luồng khác, các luồng khác sẽ không! xem liên kết: Cleanest Way to Invoke Cross-Thread Events

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