Vì vậy, một số loại danh sách ràng buộc tra cứu nhanh ... Đây là một trong những điều tôi đã chuẩn bị trước đó.
Đây là phương pháp 'đồng bộ hóa/bản đồ' mà bạn đã đề cập đến. Tôi đã sử dụng điều này trước đây để có dữ liệu đánh dấu nhanh, nơi nút cổ chai chính đang tìm kiếm các mục trong danh sách. Tôi tin rằng tôi đã đề cập đến tất cả các phương pháp cần thiết để giữ đồng bộ hóa hoặc 'được tổ chức'. Bạn có thể thêm một thử nghiệm cho AddRange - Tôi không có một trình biên dịch ngược để bàn tay, tôi không chắc chắn nếu nó chỉ gọi InsertItem. Rõ ràng là bạn có một sự cân bằng trực tiếp ở đây sử dụng bộ nhớ lớn hơn và thời gian chèn, duy trì hai danh sách, nhưng đối với dữ liệu đánh dấu nhanh, đó là một thương mại rất chấp nhận được để cải thiện thời gian tra cứu.
Sử dụng lớp như bạn sẽ là BindingList
, nhưng khi bạn cần tra cứu một mục nhanh chóng, hãy sử dụng phương pháp FastFind.
public class FastLookupBindingList<TKey, TVal> : BindingList<TVal>
{
private readonly IDictionary<TKey, TVal> _dict = new Dictionary<TKey, TVal>();
private readonly Func<TVal, TKey> _keyFunc;
public FastLookupBindingList(Func<TVal, TKey> keyFunc)
{
_keyFunc = keyFunc;
}
public FastLookupBindingList(Func<TVal, TKey> keyFunc, IList<TVal> sourceList) : base(sourceList)
{
_keyFunc = keyFunc;
foreach (var item in sourceList)
{
var key = _keyFunc(item);
_dict.Add(key, item);
}
}
public TVal FastFind(TKey key)
{
TVal val;
_dict.TryGetValue(key, out val);
return val;
}
protected override void InsertItem(int index, TVal val)
{
_dict.Add(_keyFunc(val), val);
base.InsertItem(index, val);
}
protected override void SetItem(int index, TVal val)
{
var key = _keyFunc(val);
_dict[key] = val;
base.SetItem(index, val);
}
protected override void RemoveItem(int index)
{
var item = this[index];
var key = _keyFunc(item);
_dict.Remove(key);
base.RemoveItem(index);
}
protected override void ClearItems()
{
_dict.Clear();
base.ClearItems();
}
}
Cách sử dụng:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
private void simpleButton1_Click(object sender, EventArgs e)
{
var keyedBindingList = new FastLookupBindingList<int, Person>(p => p.Id)
{
new Person {Id = 1, Name = "Joe"},
new Person {Id = 2, Name = "Josephine"}
};
var person = keyedBindingList.FastFind(2);
var unkonwn = keyedBindingList.FastFind(4);
}
Nguồn
2012-03-06 11:56:43
thx stevenP! tôi chưa bao giờ thấy giải pháp của bạn. Tôi sẽ thực hiện điều này bây giờ ans xem cách nó hoạt động. nó trông tốt mặc dù và đây là những gì tôi đã cố gắng để trước nhưng không thể có được sự đồng bộ tại chỗ –
Làm thế nào bạn sẽ làm cho threadafe này. Chúng tôi có cùng một trường hợp sử dụng trong đó một backgroundthread cập nhật danh sách liên kết được lập chỉ mục. Tuy nhiên, việc sử dụng triển khai của bạn sẽ gây ra sự cố đồng bộ hóa. Thêm khóa ở khắp mọi nơi, cũng làm tổn thương hiệu suất. – Rik
Bạn có thể sử dụng ISynchronizeInvoke.Invoke để thực hiện các cập nhật của mình không? Tức là, hãy sử dụng nhân viên nền để thực hiện nhiệm vụ truy xuất/xử lý dữ liệu của bạn trong thời gian dài, sau đó khi nó sẵn sàng, hãy gọi Invoke để nhận chủ đề UI và cập nhật BindingList? –