диспетчер для NotificationObject - PullRequest
1 голос
/ 06 января 2012

У меня есть 2 объекта NotificationObject, которые действуют как модели представления. Первый NotificationObject содержит свойства, которые связаны с представлением определенного элемента управления, а второй NotificationObject имеет некоторый код, который выполняется в другом потоке с использованием объекта Thread. Мне нужно изменить свойства первого NotificationObject из запущенного кода второго NotificationObject. Когда я пытаюсь сделать это, я получаю исключение «Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им».

Я думаю, что мне нужно использовать какой-то диспетчер для доступа к этим свойствам, как в Windows Forms или классическом WPF, но я не могу найти, как это сделать в Prism MVVM. Итак, как мне изменить свойства первого NotificationObject?

Ответы [ 3 ]

4 голосов
/ 06 января 2012

Я предполагаю, что у вас есть что-то, созданное в одном потоке, и вы пытаетесь обновить это из другого потока, а WPF этого не позволяет.Объекты могут быть изменены только из потока, в котором они были созданы.

Обычно все объекты создаются в основном потоке пользовательского интерфейса, а диспетчер используется для передачи асинхронных сообщений в поток пользовательского интерфейса для обновления этих объектов.Любую тяжелую обработку все еще можно выполнить в фоновом потоке, однако для обновления свойства объекта вам необходимо использовать основной поток пользовательского интерфейса.

Например, что-то, что выглядит так, будет работать:

MyNotificationObject obj = new MyNotificationObject;
obj.Items = MethodThatRunsOnBackgroundThread();

List<SomeObject> MethodThatRunsOnBackgroundThread()
{
    var list = new List<SomeObject>();
    // Do Work
    Return list;
}

Хотя этого не произойдет:

MyNotificationObject obj = new MyNotificationObject;
MethodThatRunsOnBackgroundThread(obj);

void MethodThatRunsOnBackgroundThread()
{
    var list = new List<SomeObject>();
    // Do Work

    // This won't work since obj was created on UI thread
    obj.Items = List<SomeObject>;
}

Вот еще один пример, который работает, поскольку он отправляет сообщение для обновления объекта в поток пользовательского интерфейса, который создал объект.

MyNotificationObject obj = new MyNotificationObject;
MethodThatRunsOnBackgroundThread(obj);

void MethodThatRunsOnBackgroundThread()
{
    var list = new List<SomeObject>();

    // Load List

    Application.Current.Dispatcher.BeginInvoke(DispatherPriority.Background,
        new Action(delegate { 
            obj.Items = list;
        }));
}
0 голосов
/ 06 января 2012

Пришлось искать Dispatcher в объекте UserControl представления, а не в NotificationObject представления модели. Я думаю, что нехорошо ссылаться на представления из представлений модели в MVVM, но лучшего решения пока не найдено.

0 голосов
/ 06 января 2012

Application.Current.Dispatcher - в значительной степени самое простое решение ..

В .NET 4.5 это, к счастью, больше не понадобится.

...