Strange MessageBus behaviour

May 8, 2012 at 3:27 PM
Edited May 8, 2012 at 3:33 PM


I've run into a strange problem. Lets say I want to create a message generator (name it ViewModel1/UserControl1), and two listeners (ViewModel2/UserControl2). Generator generates a message every second, and both listeners catch them and, as an indication, displays how many messages they have already received. All of them are completely unaware of each other. As a result on the screen, I expect to see two equal numbers being incremented every second. So:

1. I create a new ViewModel and name it ViewModel1. Inside it, I create a timer which sends a message to MessageBus every 1000ms:


        System.Timers.Timer timer;
        public ViewModel1() {
            timer = new System.Timers.Timer() { Interval = 1000, AutoReset = true };
            timer.Elapsed += (sender, e) =>  SendMessage("Timer event",new NotificationEventArgs());

2. Now I create a ViewModel2, which listens for messages and increment a local property when the message arrives:

public ViewModel2() {
            RegisterToReceiveMessages("Timer event", (sender, e) => { MyProperty++; });

private int myProperty;
        public int MyProperty {
            get { return myProperty; }
            set {
                myProperty = value;
                NotifyPropertyChanged(m => m.MyProperty);

3. For each ViewModel a View is created (named UserControl1 and UserControl2). Usercontrol1 is almost empty (only DataContext is added):

<UserControl x:Class="SimpleMvvmWpf2.Views.UserControl1"
             DataContext="{Binding Source={StaticResource Locator}, Path=ViewModel1}"
d:DesignHeight="300" d:DesignWidth="300"> <Grid> </Grid> </UserControl>

UserControl2 contains only one Label bound to MyProperty:

<UserControl x:Class="SimpleMvvmWpf2.Views.UserControl2"
             DataContext="{Binding Source={StaticResource Locator}, Path=ViewModel2}"
d:DesignHeight="300" d:DesignWidth="300"> <Grid> <Label Content="{Binding Path=MyProperty}"></Label> </Grid> </UserControl>

4. Locator code is also trivial:
        // Create ViewModel1 on demand
        public ViewModel1 ViewModel1 {
            get { return new ViewModel1(); }

        // Create ViewModel2 on demand
        public ViewModel2 ViewModel2 {
            get { return new ViewModel2(); }
5. In MainWindow.xaml, I add UserControl1 (to generate messages) and two UserControl2 (to catch messages):
<Window x:Class="SimpleMvvmWpf2.MainWindow"
        Title="MainWindow" Height="350" Width="525" >

6. That is all I've done.

On the screen, the first number stays 0, but the second is incremented by 2 every second. Am I missing something?.. It looks like I've created two separate instances of ViewModel2, but the second ViewModel steals the message from the first one...

By the way, the number is already being incremented in the XAML designer!.. Creepy.




May 8, 2012 at 3:52 PM

Update: actually, both number are incremented! At the moment, they are "1" and "1700". Some racing conditions somewhere?..