为什么不能从不同的线程更新 ObservableCollection?

2023-11-27

在多线程 WPF 应用程序中,它是不可能更新一个ObservableCollection来自 WPF 窗口线程以外的线程。

I know 有解决方法,所以我的问题不是如何避免“这种类型的 CollectionView 不支持从与 Dispatcher 线程不同的线程更改其 SourceCollection“ 例外。

我的问题是,为什么会有这样的例外呢?为什么不允许从任何线程进行集合更新?

就我个人而言,我认为没有任何理由阻止 UI 更新ObservableCollection是从其他线程更改的。如果两个线程(包括并行线程)正在访问同一个对象,一个线程通过事件侦听对象属性的更改,另一个线程执行更改,那么它将始终有效,至少在正确使用锁的情况下是这样。那么,原因有哪些呢?


首先……我感受到你的痛苦。 Ui 线程限制可能会很痛苦......

为什么你不能更新 Ui 元素 一条不同于原来的线程 创建于 ?

我的问题是,为什么会有这样一个 例外?

简而言之,历史。 Windows 已经存在了一段时间,Gui 的某些部分工作方式嵌入在 COM 等技术中......所以改变它并不是微不足道的......很容易破坏某些东西。我确信还有很多其他问题......但是比我聪明的人需要解释它们。我相信 WPF 团队确实希望消除此限制,并且他们非常努力地工作...最后,我认为所需的核心操作系统更改数量是不可行的...所以他们继续前进...老鼠。

为什么不可能允许 来自任何线程的集合更新?

过去是,现在也是可能的……使某些东西成为线程安全的总是会牺牲一些性能并增加复杂性。在大多数情况下,应用程序不需要多线程访问。重要的是要了解,在大多数情况下,Microsoft 遵循与我们相同的规则和相同的限制。如果他们让 ObservableCollection 成为线程安全的……他们就会使用我们拥有的相同工具……锁、监视器等。他们不能像我们一样破坏 Ui 线程规则……没有魔法……相同的规则。

我知道有解决方法,所以我的 问题不在于如何避免“这个 CollectionView 的类型不 支持改变其 来自线程的 SourceCollection 与调度程序线程不同” 例外。

没有解决方法...没有什么可以解决的。 ObservableCollection 已损坏..它不是线程安全的。您必须使其或对它的访问成为线程安全的。这对于任何非线程安全的东西都是一样的......如果你需要它是线程安全的,那就让它如此。如果您使用线程,那么您就会了解锁等...使用它们..这就是它们的用途。

...阻止 UI 更新 ObservableCollection 更改自 其他线程....它总是有效的, 至少如果使用锁的话 适当地....

如果锁使用得当……完全正确!同样,微软本可以安装这些锁,但他们没有这么做,而且有充分的理由。您可以加锁。或者您可以使用其他策略来为您提供线程安全访问......很多选项。

The 任务并行库在.net4.0中提供了一些新的工具来解决这些问题。能够为任务或线程设置上下文特别有用......

  // get the Ui thread context
  _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

  Action DoInBackground = new Action(() =>
  {
    /*...In the background...
      ...process some data for an ObservableCollection...*/
  });

  Action DoOnUiThread = new Action(() =>
  { 
    /*...On the UI thread...
      ...read/write data to an ObservableCollection...*/
  });

  // start the background task
  var t1 = Task.Factory.StartNew(() => DoInBackground());
  // when t1 is done run t1..on the Ui thread.
  var t2 = t1.ContinueWith(t => DoOnUiThread(), _uiScheduler);

不要将 Ui Elements 的线程亲和性要求视为需要解决的问题......这只是它的工作方式。

C# 和 .Net 有许多可以使用的工具,可以让线程不再是一场噩梦。使用它们......它们会很有趣。

我去抽根烟。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么不能从不同的线程更新 ObservableCollection? 的相关文章

随机推荐

  • 自动加载路径和嵌套服务类在 Ruby 中崩溃

    我有多个问题需要加载 需要我的类app servicesRails 5 项目中的文件夹 我开始放弃这个问题 首先要明确的是 services 是我在整个项目中使用的简单 PORO 类 用于从控制器 模型等中抽象出大部分业务逻辑 这棵树看起来
  • 是否有一个 jQuery 解决方案,在可用时使用 CORS,并在 MSIE 上使用 XDomainRequest,在浏览器上使用 niether 时使用 JSONP?

    我愚蠢地相信所有现代浏览器都支持CORS 跨域资源共享 当我的玩具 JavaScript 工具无法在 IE9 或 Opera 上运行时 我发现前者只支持CORS通过XDomainRequest jQuery 似乎不支持 歌剧不支持CORS还
  • C# 泛型与 C++ 模板 - 需要澄清约束

    复制 C 和 Java 中的泛型与 C 中的模板有什么区别 Hi all 我是一位经验丰富的 C 程序员 但对 C 还很陌生 这些限制和泛型怎么了 为什么它的工作方式与 C 中的约束不同 C 中的约束是隐式的 并且是从您对模板类进行的实例化
  • 将大型 CSV 文件加载到核心数据中的最快方法是什么

    结论我想问题已经解决了 看起来这个问题与方法无关 但 XCode 没有在构建之间正确清理项目 看起来在所有这些测试之后 正在使用的 sqlite 文件仍然是第一个没有索引的文件 当心 XCode 4 3 2 我除了 Clean 不清理的问题
  • 以最快、最有效的方式调整 UIImage 大小

    我想将 UIImage 的大小调整为一定的宽度和高度 保持比例不变 最简单的方法是 CGSize newSize CGSizeMake 726 521 UIGraphicsBeginImageContext newSize image dr
  • 避免在 scikit learn StandardScaler 中缩放二进制列

    我正在 sci kit learn 中构建线性回归模型 并将输入缩放为 sci kit learn Pipeline 中的预处理步骤 有什么方法可以避免缩放二进制列吗 发生的情况是这些列与其他列一起缩放 导致值以 0 为中心 而不是 0 或
  • 使用 CSS 更改链接文本

    我想用 CSS 更改我的链接文本 但它不起作用 a testclass display none a testclass after content new text a class testclass href someurl com C
  • 在 Haskell 中使用填充进行压缩

    有几次我发现自己想要一个zip在 Haskell 中 它会向较短的列表添加填充 而不是截断较长的列表 这很容易写 Monoid在这里对我有用 但您也可以只传递要用于填充的元素 zipPad Monoid a Monoid b gt a gt
  • 屏幕密度为 440 dpi 的设备与 Google Play 上发布的应用不兼容

    添加后
  • 工作流/管道插件中的访问阶段结果

    我有一个具有不同阶段的管道 我希望当前的作业检查上一个构建已经经过了多少阶段并将其记录在控制台中 考虑这是我当前的管道 node stage 1 do something stage 2 do something else 我想要一个很棒的
  • 如何在 MySQL 上进行 SQL 区分大小写的字符串比较?

    我有一个函数返回五个大小写混合的字符 如果我对此字符串进行查询 无论大小写 它都会返回值 如何使 MySQL 字符串查询区分大小写 使用它来进行区分大小写的查询 SELECT FROM table WHERE BINARY column v
  • 使用 LINQ 获取每第 n 行

    我们的 SQL 数据库中有一个表 其中包含我需要用来创建图表的历史原始数据 我们通过实体框架和 LINQ 访问数据库 对于较小的日期时间间隔 我可以简单地读取数据并生成图表 var mydata entity DataLogSet Wher
  • Oracle用rownum查看性能

    我正在使用 Oracle 10g 并且有一个连接两个大表 数百万条记录 的视图 我试图为用户选择有限的数据 样本 如下所示 select from VIEW NAME where ROWNUM lt 5 它非常慢 我认为不应该 因为我只需要
  • 添加许多约束时 PuLP 非常慢

    我正在尝试使用 PuLP 但它需要50秒添加 4000 个约束 包含 67 个变量 解决问题只需要几分之一秒的时间 我们希望使用 PuLP 轻松测试大量问题的多个求解器 PuLP 应该花这么长时间吗 直接使用 PyGLPK 只需要几分之一秒
  • 在Java中解析Java的最佳方法

    正如标题所说 我想用Java解析一些Java源代码 我很确定还有其他 java 库已经执行此操作 但我找不到任何库 Antlr 有一个 Java 语法文件 看this
  • XPath:通过*纯*文本查找 HTML 元素

    请注意 这个问题的更精致的版本 可以找到适当的答案here 我想使用 Selenium Python 绑定来查找网页上具有给定文本的元素 例如 假设我有以下 HTML
  • 软件测试工具 - 用于java [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 有人能给我列出 5 个在
  • ASP.NET MVC - 在 RegisterGlobalFilters() 中使用 ActionFilterAttribute 时 Response.Filter 为 null

    我想在我的网站上使用 G ZIP 我用 google 搜索了以下代码 public class CompressAttribute ActionFilterAttribute public override void OnActionExe
  • 如何终止 setTimeout() 函数

    我通过我的应用程序使用 setTimeout 函数 但是当需要进行垃圾收集时 该方法仍然运行并调用函数 如何阻止它调用某个函数 我尝试将其设置为 null 但不起作用 设置超时时间返回对超时的引用 然后您可以在调用时使用它清除超时 var
  • 为什么不能从不同的线程更新 ObservableCollection?

    在多线程 WPF 应用程序中 它是不可能更新一个ObservableCollection来自 WPF 窗口线程以外的线程 I know 有解决方法 所以我的问题不是如何避免 这种类型的 CollectionView 不支持从与 Dispat