Доступ к свойствам ViewModel из отдельного потока - PullRequest
6 голосов
/ 15 декабря 2011

В моем приложении wpf трудоемкая операция в моей модели представления вызывается с использованием отдельного потока.Эта функция, однако, получает доступ к нескольким свойствам в модели представления, которые связаны с объектами в представлении.Я попытался получить к ним доступ напрямую и не вижу жалоб на то, что они принадлежат потоку пользовательского интерфейса.Мне интересно знать последствия использования их напрямую между потоками.

Ответы [ 3 ]

5 голосов
/ 15 декабря 2011

Вы можете свободно использовать свою ViewModel из любого потока, включая чтение и запись.Единственное основное исключение касается работы с коллекциями - коллекции, связанные с данными, должны быть записаны в потоке пользовательского интерфейса, поскольку привязка не выполняется автоматически в потоке пользовательского интерфейса (как это делают простые привязки).

Однако вывсе же следует рассмотреть вопрос о наличии надлежащей синхронизации для любых записей.Возникнут обычные проблемы с синхронизацией потоков, поскольку ViewModel - это просто еще один класс.

При этом, как правило, вы захотите обрабатывать синхронизацию немного иначе, чем во многих случаях.Блокировки обычно не работают в ViewModel, поскольку привязка данных WPF не блокирует объекты.Поэтому обычно следует использовать Dispatcher.Invoke / BeginInvoke для перенаправления вызовов обратно в поток пользовательского интерфейса, когда это необходимо, когда требуется синхронизация во ViewModel.

1 голос
/ 15 декабря 2011

Никаких последствий, кроме ваших обычных проблем с безопасностью нитей, не будет. Единственное, что обычно проблематично для свойств виртуальных машин, это ObservableCollections, которые имеют сродство с потоками.

0 голосов
/ 16 декабря 2011

Если вы используете расширение ObservableCollection с этим, вы можете обновить из отдельного потока:

/// <summary>
/// Source: New Things I Learned
/// Title: Have worker thread update ObservableCollection that is bound to a ListCollectionView
/// http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx
/// Note: Improved for clarity and the following of proper coding standards.
/// </summary>
/// <param name="e"></param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
    // Use BlockReentrancy
    using (BlockReentrancy())
    {
        var eventHandler = CollectionChanged;

        // Only proceed if handler exists.
        if (eventHandler != null)
        {
            Delegate[] delegates = eventHandler.GetInvocationList();

            // Walk thru invocation list
            foreach (NotifyCollectionChangedEventHandler handler in delegates)
            {
                var currentDispatcher = handler.Target as DispatcherObject;

                // If the subscriber is a DispatcherObject and different thread
                if ((currentDispatcher != null) &&
                    (currentDispatcher.CheckAccess() == false))
                {
                    // Invoke handler in the target dispatcher's thread
                    currentDispatcher.Dispatcher.Invoke(
                        DispatcherPriority.DataBind, handler, this, e);
                }

                else
                {
                    handler(this, e);
                }
            }
        }
    }
}

/// <summary>
/// Overridden NotifyCollectionChangedEventHandler event.
/// </summary>
public override event NotifyCollectionChangedEventHandler CollectionChanged;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...