即使在 .NET 4.5 中,ObservableCollection 也不是线程安全的?

2024-04-16

这几天我一直在用头撞虚拟墙。 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(使用前将#替换为@)

即使在 .NET 4.5 中,ObservableCollection 也不是线程安全的? 的相关文章

随机推荐

  • 如何使用 .NET 2.0 捕获 using 块中的异常?

    这些天 当我有一个实现 IDisposable 的对象时 我尝试越来越多地利用 using 块 但我还没有弄清楚的一件事是如何像在正常的 try catch finally 中一样捕获异常 有任何代码示例可以为我指明正确的方向吗 编辑 阅读
  • 如何更改JavaFX中ListView的字体大小?

    我尝试了这个建议http forums sun com thread jspa threadID 5421037 http forums sun com thread jspa threadID 5421037但找不到风格 还有其他办法吗
  • 使用多次调用函数的 Angular @Input 绑定

    我在用着角8 我有一个子组件 Input 财产 必须在绑定之前修改此输入 因此使用方法返回用于绑定的数据 例如
  • 联系表 7 - 自定义验证

    我只需要验证一个字段 称为 实例 以仅接受小写 ASCII 字母和数字 第一个字符也必须是字母而不是数字 它会接受大写字符 但我们需要它在输入时将它们小写 因此 如果有人使用实例名称 McDonalds 它将小写为 mcdonalds 不仅
  • django 中的实时通知/聊天

    我现在正在用 django 制作一个网站 我想实现一个实时通知功能 就像 facebook 或 SE 上的那样 我做了一些研究 似乎虽然有两种选择 ajax 长轮询和 websockets 但后者是最佳选择 然而 正如你所知 websock
  • onEdit 简单触发器似乎永远不会被触发

    我一直在使用OnEdit一段时间以来 它一直工作得很好 但是现在我遇到了一个问题 基本上当编辑第 6 列 f 时 我希望它检查该值 如果它是 正在进行 我希望它然后运行一个函数发送电子邮件 当我调试它时 它完全按照我想要的方式工作 但是当我
  • 我的 Qt5 可执行文件无法在 Visual Studio 2010 之外运行

    我用 Qt5 和 Visual Studio 2010 完成了一个大项目 使用运行按钮 一切都在 Visual Studio 内部 但我的目标当然是在没有视觉工作室的情况下将其发布给其他人 我的问题是 我无法在 Visual Studio
  • Vue.js 中的 $t 是什么

    第一次与Vue js并且不知道是什么 t 例如我有一个人的代码是这样的 li class category filter back li
  • 如何使用 SVM 预测多类情感分析问题中的所有类?

    好吧 我正在制作一个情感分析分类器 我有三个类别 标签 积极 中性和消极 我的训练数据的形状是 14640 15 其中 negative 9178 neutral 3099 positive 2363 我对数据进行了预处理 使其标准化 并将
  • 如何使用swagger-codegen-maven-plugin生成spring cloud feign客户端

    我想使用 swagger codegen 生成我的假客户端代码 但我找不到可以引导我执行此操作的文档 我有一个使用 spring cloud 的微服务 几个使用 spring cloud feign 接口来请求数据的 api 服务 我希望我
  • “require(x)”和“import x”之间的区别

    我刚刚开始开发一个将与 MongoDB 交互的小型节点项目 但是 我似乎无法正确导入相关的节点模块 即使我已经通过以下方式正确安装了它们npm 例如 以下代码会抛出错误 告诉我 express 没有默认导出 import express f
  • java中如何将一个线程与另一个线程连接起来?

    我有一个主线程启动其他 10 个线程 我希望只有在所有其他线程停止后主线程才会完成 那么我应该在其他 10 个线程启动之前或启动之后调用 join 吗 例如 in the main method of Main thread Thread
  • 如何设置 nginx 以允许在 LAN 上使用 HTTP,并在外部连接上进行重定向和授权

    我正在尝试为我在家庭服务器上运行的一些个人 Web 服务设置 Nginx 网络在服务器和互联网之间设置了路由器 该路由器运行着动态 DNS 服务 以便我可以在不在家时连接到它 我希望 Nginx 能够处理来自本地网络的连接 以便它能够通过以
  • 为一个参数指定多个接口

    我有一个实现两个接口的对象 接口是 public interface IObject string Name get string Class get IEnumerable
  • 像 c# 中的列表一样用括号初始化元素

    我正在考虑数组和列表 想知道类是否以及如何获得像它们一样可初始化的实现 让我们以这个类为基础 class TestClass private List
  • Symfony 2.* 中漂亮的转储变量/对象?

    在开发东西时 我需要输出某个实例的状态以便检查它 在使用 CakePHP 时 我总是有一个 debug 函数 它在 html 元素内执行某种 var dump 因此内容是可读的 Symfony 2 x 中也有类似的东西吗 exit Doct
  • 没有权限从任务计划程序写入文件?

    我得到了一个批处理文件 它将运行 C 程序并输出到带有 gt 重定向的文件 该文件将由任务调度程序运行 我发现当从任务计划程序运行批处理文件时 它声称 访问被拒绝 批处理文件运行良好 直到到达 gt 重定向部分 我看到整个批次可以在没有 g
  • XCode - 架构 armv7 arm64 的未定义符号

    我参与了一个较旧的项目 该项目需要为其使用的扫描仪更新 SDK 新的 SDK 已支持 64 位 因此应用程序需要更新 SDK是通过拖放到项目中安装的 但之后在构建时出现以下错误 注意 我收到一个错误 指的是arm64但这目前说armv7因为
  • 是否可以托管 Java Web 服务而不将其部署在 Tomcat/JBoss 等服务器上?

    据我所知 需要 Apache Tomcat 或像 JBoss 这样的应用服务器来部署和运行用 java 实现的 Web 服务 我的经理问我 是否有其他方法可以在不配置或设置 Apache Tomcat JBoss 的情况下部署 Web 服务
  • 即使在 .NET 4.5 中,ObservableCollection 也不是线程安全的?

    这几天我一直在用头撞虚拟墙 BindingOperations EnableSynchronization 方法似乎仅在 NET 4 5 中部分工作 我写了一个有时会失败的测试 object blah new object Applicat