tôi đã viết này rất nhanh chóng và đã không kiểm tra nó, và tôi chỉ đăng tải nó để truyền tải ý tưởng chung, của một phương pháp tiếp cận khóa có điều kiện, sử dụng các phương thức mở rộng, và các đại biểu hoặc hàm lambda. Tôi cũng không thể nói mà không cần kiểm tra, nếu điều này có thể tự đánh bại, điều chắc chắn là có thể.
Tôi có mã chạy trong cả hai quy trình đa luồng và quy trình sử dụng mô hình luồng chế độ sợi hợp tác (ví dụ: nơi có nhiều luồng không bao giờ thực thi không đồng bộ). Trong ứng dụng chế độ sợi hợp tác, khóa là vô nghĩa và lãng phí, vì vậy đây có thể là một giải pháp để tránh rất nhiều logic lộn xộn tại mỗi điểm mà khóa phải được thực hiện.
// Conditional Locking concept code
namespace SystemExtensions {
public static class LockMeUp
{
private static bool isLockingEnabled = true;
// If set to true, locking will be performed
// by the extension methods below.
internal static bool LockingEnabled
{
get
{
return isLockingEnabled;
}
set
{
isLockingEnbaled = value;
}
}
static void CheckNull<TLock>(TLock target) where TLock: class
{
if(target == null)
throw new ArgumentNullException("target cannot be null");
}
// Invoke the supplied action on the supplied lock object
public static void TryLock<TLock>(
this TLock target,
Action<TLock> action) where TLock: class
{
CheckNull(target);
if(isLockingEnabled)
{
lock(target)
{
action(target);
}
}
else
{
action(target);
}
}
// Invoke the supplied function on the supplied
// lock object and return result:
public static T TryLock<TLock, T>(
this TLock target,
Func<TLock, T> func) where TLock: class
{
CheckNull(target);
if(isLockingEnabled)
{
lock(target)
{
return func(target);
}
}
else
{
return func(target);
}
}
// Invoke the supplied function on the supplied lock object
// and another supplied argument, and return the result:
public static T TryLock<TLock, TArg, T>(
this TLock target,
Func<TLock, TArg, T> func,
TArg arg) where TLock: class
{
CheckNull(target);
if(isLockingEnabled)
{
lock(target)
{
return func(target, arg);
}
}
else
{
return func(target, arg);
}
}
// Invoke the supplied action on the supplied lock object
// and another supplied argument:
public static void TryLock<TLock, TArg>(
this TLock target,
Action<TLock, TArg> func,
TArg arg) where TLock: class
{
CheckNull(target);
if(isLockingEnabled)
{
lock(target)
{
func(target, arg);
}
}
else
{
func(target, arg);
}
}
}
///// Example:
public static class SharedList<T>
{
private static List<T> items = new List<T>();
public static bool Remove(T item)
{
return items.TryLock((list, item) => list.Remove(item), item);
}
public static T GetItemAt(int index)
{
return items.TryLock((list, i) => list[i], index);
}
public static bool Contains(T item)
{
return items.TryLock((list, it) => list.Contains(it), item);
}
public static void Add(T item)
{
items.TryLock((list, item) => list.Add(item));
}
}
} // namespace
Trong quyết định này, bạn cũng phải đánh giá: khóa sẽ không bị phát hiện (ví dụ: mức độ xảy ra ** bên trong ** khóa sẽ làm tăng đáng kể tỷ lệ tranh chấp). Tùy thuộc vào kịch bản, có thể tốt hơn để thực hiện kiểm tra chính hãng đôi hoặc bạn có thể không khóa. Kể từ khi tài liệu tham khảo được đảm bảo nguyên tử, di chuyển dữ liệu đến một đối tượng bất biến và dereferencing nó có thể được khá dễ thương (trong kịch bản bên phải). –