这几天我一直在用头撞虚拟墙。
BindingOperations.EnableSynchronization 方法似乎仅在 .NET 4.5 中部分工作。
我写了一个有时会失败的测试:
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);
TestCollectionWindow 看起来像这样:
<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>
所以这里没什么神奇的。但结果是几乎每次某些条目在 UI 中出现两次 - 相同的对象!
结果窗口如下所示:
桑德拉·布洛克 1
詹妮弗·安妮斯顿 2
詹妮弗·洛佩兹 3
安吉丽娜·朱莉 4
玛丽·伊丽莎白·马斯特兰托尼奥 5
詹妮弗·安妮斯顿 2
正如您可以清楚地看到詹妮弗·安妮斯顿被列出两次。这可以很容易地重现。
这是一个普遍问题还是这个测试有什么问题,例如有缺陷的应用程序实例化?
先感谢您!
班级是有记录的 http://msdn.microsoft.com/en-us/library/ms668604.aspx不是线程安全的:
线程安全
此类型的任何公共静态(在 Visual Basic 中为共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。
所以不,它不是线程安全的。
注意BindingOperations.EnableCollectionSynchronization http://msdn.microsoft.com/en-us/library/hh198845.aspx不会神奇地使整个集合成为线程安全的。它仅告诉绑定系统您打算使用哪个锁定对象,以防止多个线程同时访问集合。
由于您实际上并未使用锁定对象,因此您最好不调用该方法,结果同样不可预测。
尝试发出lock
on the blah
围绕访问集合的每个语句的对象。不幸的是,我不知道 WPF 中数据绑定的详细信息,因此我不知道这是否足够。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)