Сначала ... Я чувствую твою боль.Ограничение потока пользовательского интерфейса может быть проблемой ...
Почему вы не можете обновить элемент пользовательского интерфейса из потока, отличного от того, в котором он был создан?
Мой вопроспочему есть такое исключение?
Ну в двух словах история.Windows существует уже давно, и то, как некоторые части работы с графическим интерфейсом встроены в такие технологии, как COM и т. Д., Поэтому изменение ее не является тривиальным ... было бы очень легко что-то сломать.Я уверен, что есть много других проблем ... но кто-то умнее меня должен их объяснить.Я полагаю, что команда WPF действительно хотела снять это ограничение, и они работали над этим довольно усердно ... В конце концов, я думаю, что количество изменений в основной ОС было неосуществимым ... поэтому они пошли дальше ... крысы.
Почему нельзя было разрешить обновления коллекций из какого-либо потока?
Есть и возможно ... Создание чего-то поточно-безопасного всегда стоит некоторых с точки зрения производительности и добавлениясложность.В большинстве случаев приложение не требует многопоточного доступа.Важно понимать, что, по большей части, Microsoft играет по тем же правилам, что и мы, и с теми же ограничениями.Если бы они сделали ObservableCollection поточно-безопасным ... они бы использовали те же инструменты, что и у нас ... блокировки, мониторы и т. Д. Они не могут нарушить правило потока Ui больше, чем мы ... без магии ...те же правила.
Я знаю, что есть обходные пути, поэтому мой вопрос не в том, как избежать исключения «Этот тип CollectionView не поддерживает изменения в его SourceCollection из потока, отличного от потока Dispatcher».
Обходных путей нет ... Обходных путей нет.ObservableCollection не работает .. она просто не поточнобезопасна.Вы должны сделать его или доступ к нему потокобезопасным.Это то же самое для всего, что не является поточно-ориентированным ... если вам нужно, чтобы оно было поточно-ориентированным, сделайте это так.Если вы используете потоки, то вы знаете о блокировках и тому подобном ... используйте их ... для этого они и предназначены.
... обновление пользовательского интерфейса блока при изменении ObservableCollection из других потоков .... он всегда будет работать, по крайней мере, если замки используются правильно ....
Если замки используются правильно ... Точно!Опять же, Microsoft могла бы установить эти блокировки, но они этого не сделали и по очень веским причинам.Вы можете установить блокировки. Или использовать другую тактику, которая предоставит вам потокобезопасный доступ ... множество опций.
Параллельная библиотека задач в .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 имеют много инструментов, которые вы можете использовать, что делает многопоточность чуть менее кошмарным.Используйте их .. они могут быть забавными.
Я пойду покурю.