Nhảy khỏi this thread, tôi đang cố gắng để sử dụng ConcurrentDictionary để tái tạo như sau:.NET4.0: Chủ đề An toàn cập nhật của ConcurrentDictionary <TKey, TValue>
public static class Tracker
{
private static Dictionary<string, int> foo = new Dictionary<string, int>();
private static object myLock = new object();
public static void Add(string bar)
{
lock(myLock)
{
if (!foo.ContainsKey(bar))
foo.Add(bar, 0);
foo[bar] = foo[bar] + 1;
}
}
public static void Remove(string bar)
{
lock(myLock)
{
if (foo.ContainsKey(bar))
{
if (foo[bar] > 0)
foo[bar] = foo[bar] - 1;
}
}
}
}
nỗ lực ban đầu của tôi là:
public static class Tracker2
{
private static ConcurrentDictionary<string, int> foo =
new ConcurrentDictionary<string, int>();
public static void Add(string bar)
{
foo.AddOrUpdate(bar, 1, (key, n) => n + 1);
}
public static void Remove(string bar)
{
// Adding a 0'd item may be ok if it wasn't there for some reason,
// but it's not identical to the above Remove() implementation.
foo.AddOrUpdate(bar, 0, (key, n) => (n > 0) ? n - 1 : 0);
}
}
Đây có phải là cách sử dụng chính xác không? Tôi sẽ tránh được những tình huống như:
- Chủ đề 1: các cuộc gọi Thêm ("a"), foo [ "a"] tại là 1.
- Chủ đề 1 được chuyển ra cho Chủ đề 2.
- Chủ đề 2: cuộc gọi Xóa ("a"), foo ["a"] hiện là 0.
- Chủ đề 2 được hoán đổi cho Chủ đề 1.
- Chủ đề 1: Yêu cầu foo ["a"] và giả định giá trị là 1 nhưng nó thực sự là 0.
Điểm tốt. Đã chỉnh sửa để phản ánh sự tương đương với việc triển khai từ điển. – Bullines
's_ConcurrentRequests' và' url' là gì? Ngoài ra tôi cập nhật câu trả lời của tôi để chỉ ra một sự tương đương với phương thức 'Add'. – Domenic
Interlocked.Decrement có thể là ok, nhưng tôi sẽ phải đảm bảo các giá trị lớn hơn 0. Điều này có thể là ok, bởi vì các giá trị không bao giờ nên nhỏ hơn 0. Nhưng mẹo sẽ là có cách an toàn để kiểm tra xem giá trị có lớn hơn 0 không. Có lẽ Interlock.Exchange? – Bullines