使用NServiceBus

时间:2017-02-12 16:24:25

标签: c# wpf mvvm messaging nservicebus

我的MVVM应用程序中有一个ObservableCollection的奇怪行为,更确切地说是负责从NServiceBus接收消息的代码部分:

public class MyViewModel: ViewModelBase, IHandleMessages<CarMoved>
{
 public ObservableCollection<CarData> Cars= new ObservableCollection<CarData>();


 public Task Handle(CarMoved message, IMessageHandlerContext context)
 {
   ...
   Cars.Add(new Car());

   return Task.CompletedTask;
 }

}

所以我希望Handle方法在我的ObservableCollection中添加一个新对象,但对象的数量保持不变。 我创建了测试按钮以检查是否可以使用按钮添加新对象,此测试按钮工作正常。 我还调试了Handle方法,我可以看到Obludeable集合中的对象数量增加,而我在Handle方法中,但是一旦我离开方法,所有这些都会改变 - 对象的数量返回到旧的数字

我尝试使用Task.Run(..)添加对象; Task.Wait();假设它可能需要一些时间。它没有帮助。

请告知我如何解决此问题及其发生的原因?

2 个答案:

答案 0 :(得分:4)

好的,这里的问题是NServiceBus将创建一个ViewModel的新实例来处理消息。这显然不是你想要的。

相反,ViewModel和消息Handler应该是单独的对象。然后处理程序可以告诉ViewModel有关消息。

我不确定您使用的MVVM框架,但通常会有某种事件聚合器用于传递来自NServiceBus处理程序和ViewModel等系统组件的消息。

答案 1 :(得分:0)

确保使用调度程序访问UI线程上的ObservableCollection

public Task Handle(CarMoved message, IMessageHandlerContext context)
{
    Application.Current.Dispatcher.BeginInvoke(new Action(() => { Cars.Add(new Car()); }));

    return Task.CompletedTask;
}

或者,您可以尝试使用BindingOperations.EnableCollectionSynchronization方法来跨多个线程访问集合:

public class MyViewModel : ViewModelBase, IHandleMessages<CarMoved>
{
    private readonly object _lock = new object();
    public ObservableCollection<CarData> Cars = new ObservableCollection<CarData>();

    public MyViewModel()
    {
        Application.Current.Dispatcher.Invoke(() => BindingOperations.EnableCollectionSynchronization(Cars, _lock));
    }

    public Task Handle(CarMoved message, IMessageHandlerContext context)
    {
        Cars.Add(new Car());
        return Task.CompletedTask;
    }
}

如果你仍然无法做到,你应该阅读:https://stackoverflow.com/help/mcve