为什么不是可以更新来自不同的线程一个ObservableCollection? [英] Why isn't it possible to update an ObservableCollection from a different thread?

查看:1888
本文介绍了为什么不是可以更新来自不同的线程一个ObservableCollection?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在多线程WPF应用程序,它是不可能以更新的ObservableCollection 从比WPF窗口线程的线程上。



我知道有变通方法,所以我的问题不在于如何避免这种类型的CollectionView不支持其SourceCollection从一个线程不同于调度线程变化的异常。



我的问题是,为什么会出现这样的异常?为什么是不是可以允许从任何线程集合类的更新?



就个人而言,我看不出有任何理由,当的ObservableCollection 从其他线程改变阻止UI更新。如果两个线程(包括平行的)访问相同的对象,一收听通过事件对象属性的变化,另外一个做的改变,它会一直工作,至少如果锁被正确使用。那么,是什么原因?


解决方案

首先......我觉得你的痛苦。 UI线程限制,可以是一个痛苦...




为什么不能从你比其他
A线程更新UI元素一有人
创建了?



我的问题是,为什么有这样的
例外呢?


< /块引用>

井简而言之,历史。 Windows已经存在了一段时间,桂工作的某些部分嵌入技术,如COM和喜欢的方式....所以更改它是不平凡的......会很容易碰坏。还有我敢肯定,许多其他问题......但有人比我聪明就需要解释。我相信WPF队真的想取消这一限制,他们在它的工作相当困难......最后,我认为核心操作系统更改的数量需求是不可行的......所以他们移动了....老鼠。




为什么是不是可以允许从任何线程
集合类的更新?




是过去和现在都是可能的...使一些线程安全的成本总是在一些性能和增加复杂性。在大多数情况下,应用程序不要求多线程访问。理解的是,在大多数情况下,微软起着由我们做同样的规则和相同的限制是重要的。如果他们所取得的的ObservableCollection线程安全的......他们会用我们拥有相同的工具...锁定,监视器等,他们无法打破UI线程规则的任何比我们......没有魔法更多...同样的规则。




我知道有解决方法,所以我的
的问题不在于如何避免本
的CollectionView的类型并不
的支持,它的
SourceCollection从一个线程
从发送器线程
例外不同的变化。




有没有解决办法?有什么要解决。本的ObservableCollection是broken..it仅仅是不是线程安全的。你必须做,或者访问它,线程安全的。这是什么,是不是线程安全的...如果你需要它是线程安全的,然后做起来很一样。如果你正在使用线程,那么你知道锁,这样......使用them..that是他们所为。




..当
的ObservableCollection从
其他线程改变......它会永远工作,
。至少,如果使用锁
正确....




如果锁正确使用...没错!同样,微软可能已经把这些锁,但他们并没有和有很好的理由。你可以把锁可。或者你用其他的战术,这将使你线程安全的访问....很多的选择。



在.net4.0任务并行库提供了解决这些问题的一些新的工具。能够设置一个上下文任务或线程是非常有用的...

  //获取UI线程上下文
_uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

行动DoInBackground =新的行动(()=>
{
/*...In背景...
...过程中的一些数据一个ObservableCollection ... * /
});

行动DoOnUiThread =新的行动(()=>
{
/*...On UI线程...
...读/写数据到一个ObservableCollection ... * /
});

//启动后台任务
变种T1 = Task.Factory.StartNew(()=> DoInBackground());
当T1完成运行t1..on UI线程//。
变种T2 = t1.ContinueWith(T => DoOnUiThread(),_uiScheduler);



不要去想UI元素的线程关联性要求的东西来解决....它仅仅是它的工作方式。



C#和.NET都可以使用,使线程恶梦少一点的工具。使用them..they可以很有趣。



我要为烟。


In a multi-threaded WPF application, it is not possible to update an ObservableCollection from a thread other than WPF window thread.

I know there are workarounds, so my question is not how to avoid the "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread" exception.

My question is, why there is such an exception? Why wasn't it possible to allow collection updates from any thread?

Personally, I don't see any reason to block UI update when ObservableCollection is changed from other threads. If two threads (including parallel ones) are accessing the same object, one listening for changes of object properties through events, the other one doing changes, it will always work, at least if locks are used properly. So, what are the reasons?

解决方案

First...I feel your pain. The Ui thread restriction can be a pain...

Why can't you update a Ui Element from a thread other than the one it was created on ?

My question is, why there is such an exception?

Well in a nutshell, history. Windows has been around a while and the way some parts of the Gui work are embedded in technologies such as COM and the like....so changing it is not trivial...would be very easy to break something. There are many other issues I'm sure...but somebody smarter than me would need to explain them. I believe the WPF team really wanted to remove this restriction and they worked at it pretty hard...in the end I think the number of core OS changes need was unworkable...so they moved on....rats.

Why wasn't it possible to allow collection updates from any thread?

Is was and is possible... Making something thread-safe always costs some in performance and add complexity. In most cases the application doesn't call for multi thread access. It is important to understand that, for the most part, Microsoft plays by the same rules we do and the same restrictions. If they had made the ObservableCollection thread-safe ...they would have used the same tools we have...locks, monitors, etc. They cannot break the Ui thread rule any more than we can...no magic...same rules.

I know there are workarounds, so my question is not how to avoid the "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread" exception.

There are no workarounds...There is nothing to workaround. The ObservableCollection is broken..it is just not thread-safe. You must make it, or access to it, thread-safe. This is the same for anything that is not thread-safe...if you need it to be thread-safe then make it so. If you are using threads then you know about locks and such...use them..that is what they are for.

...block UI update when ObservableCollection is changed from other threads.... it will always work, at least if locks are used properly....

If locks are used properly...Exactly ! Again, Microsoft could have put these locks in but they didn't and for very good reasons. You can put the locks in. Or you use other tactics that will give you thread-safe access....lots of options.

The Task Parallel Library in .net4.0 provides some new tools for solving these problems. Being able to set a context for a task or a thread is particularly useful...

  // 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);

Don't think about the thread affinity requirements of Ui Elements as something to work around....it is just the way it works.

C# and .Net have many tools that you can use that make threading a little less of a nightmare. Use them..they can be fun.

I'm going for a smoke.

这篇关于为什么不是可以更新来自不同的线程一个ObservableCollection?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆