Tôi đập đầu vào tường ảo trong nhiều ngày. Phương thức BindingOperations.EnableSynchronization dường như chỉ hoạt động một phần trong .NET 4.5.ObservableCollection không phải là chủ đề an toàn ngay cả trong .NET 4.5?
Tôi đã viết một bài kiểm tra đó không đôi khi:
object blah = new object();
Application app = Application.Current == null ? new Application() : Application.Current;
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
ObservableCollection<ThreadSafeObservableTestObject> collection = null;
collection = new ObservableCollection<ThreadSafeObservableTestObject>();
BindingOperations.EnableCollectionSynchronization(collection, blah);
CollectionTestWindow w = new CollectionTestWindow();
Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
w.TestCollection = collection;
collection.CollectionChanged += collection_CollectionChanged;
collection.Add(new ThreadSafeObservableTestObject() { ID = 1, Name = "Sandra Bullock" });
collection.Add(new ThreadSafeObservableTestObject() { ID = 2, Name = "Jennifer Aniston" });
collection.Add(new ThreadSafeObservableTestObject() { ID = 3, Name = "Jennifer Lopez" });
collection.Add(new ThreadSafeObservableTestObject() { ID = 4, Name = "Angelina Jolie" });
collection.Add(new ThreadSafeObservableTestObject() { ID = 5, Name = "Mary Elizabeth Mastrantonio" });
Thread.Sleep(5000);
System.Windows.Application.Current.Dispatcher.Invoke(() => w.Close());
System.Windows.Application.Current.Dispatcher.Invoke(() => Application.Current.Shutdown());
});
app.Run(w);
Các TestCollectionWindow trông như thế này:
<ItemsControl ItemsSource="{Binding TestCollection}" Name="list">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding ID}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Vì vậy, không có gì kỳ diệu ở đây. Nhưng kết quả là hầu như mọi khi một số mục nhập hai lần trong giao diện người dùng - cùng một đối tượng! Cửa sổ kết quả sẽ như thế này thì:
Sandra Bullock 1
Jennifer Aniston 2
Jennifer Lopez 3
Angelina Jolie 4
Mary Elizabeth Mastrantonio 5
Jennifer Aniston 2
Như bạn có thể thấy rõ ràng Jennifer Aniston được liệt kê hai lần. Điều này có thể được sao chép dễ dàng. Đây có phải là vấn đề chung hay không có bất kỳ điều gì sai trái với bài kiểm tra này, chẳng hạn như một bản tóm tắt ứng dụng không đúng?
Cảm ơn bạn trước!
Hầu hết các lớp học tập không phải là thread an toàn và sẽ không bao giờ. An toàn chủ đề là ** cứng ** và yêu cầu các API khác nhau. Nhìn vào các bộ sưu tập đồng thời. – SLaks
Có lẽ bạn nên kiểm tra không gian tên ['System.Collections.Concurrent'] (http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx). –
Hãy thử bộ sưu tập này để giải quyết vấn đề này cũng như các vấn đề đa luồng khác chắc chắn sẽ nảy sinh với các cách tiếp cận khác: http://www.codeproject.com/Articles/64936/Multithreaded-ObservableImmutableCollection – Anthony