I am developing a multi-threaded monitor application. In addition to the "main" thread, there are 2 sets of reader-writer threads connecting to 2 instances of a production application. Part of the message flow from the production apps are EvtMsg items. These are placed by the reader thread into a ConcurrentQueue for that particular side (LEFT or RIGHT). The main window has an EvtMsg button for each side. When you click on one of them, it will bring up a window that contains a DataGrid, populated from the given ConcurrentQueue.
The problem is when I open an EvtMsg window, the DataGrid is populated with all EvtMsg objects received up to that point (say, for example, 3 items), but upon receiving new EvtMsg messages, they don't update the window (I am using INotifyPropertyChanged, and I have debugged to verify that the ConcurrentQueue has the new items).
Data structures:
public enum eSide : int { LEFT = 0, RIGHT = 1 }
public const int C_numSides = 2;
public class EvtMsg : INotifyPropertyChanged
{
public ulong sequenceNumber { get; set; }
public string description { get; set; }
}
public class AnEvtQueue : INotifyPropertyChanged
{
public ConcurrentQueue<EvtMsg> EvtQueue { get; set; }
public AnEvtQueue()
{
EvtQueue = new ConcurrentQueue<EvtMsg>();
}
}
public class EvtHandler : INotifyPropertyChanged
{
public AnEvtQueue[] Sides {get; set;}
public EvtHandler()
{
Sides = new AnEvtQueue[C_numSides];
Sides[(int)eSide.LEFT ] = new AnEvtQueue();
Sides[(int)eSide.RIGHT] = new AnEvtQueue();
}
public void AddEvtMsg(eSide WhichSide, EvtMsg msg)
{
Sides[side].EvtQueue.Enqueue(msg);
}
}
xaml:
<DataGrid Grid.Row="2"
AutoGenerateColumns="False"
IsReadOnly="True"
SelectionMode="Single"
SelectionUnit="FullRow"
GridLinesVisibility="None"
Name="StatList"
ItemsSource="{Binding NotifyOnSourceUpdated=True}">
<DataGrid.Columns>
<!-- Col 0: Sequence # -->
<DataGridTextColumn Binding="{Binding Path=sequenceNumber}"
ElementStyle="{StaticResource DGCell_RightAlignStyle}"
Header="Sequence #" />
<!-- Col 0: EvtMsg Text -->
<DataGridTextColumn Binding="{Binding Path=description}"
FontFamily="Courier New"
Header="EvtMsg Text" />
</DataGrid.Columns>
</DataGrid>
<!-- .... -->
Code-behind:
public EvtMsgWindow(eSide WhichSide)
{
public ApplicationViewModel AppVM = ApplicationViewModel.Instance;
InitializeComponent();
StatList.ItemsSource = AppVM.TheEvtHandler.Sides[(int)WhichSide].EvtQueue;
}
}
What I have tried:
I had tried an ObservableCollection, but this didn't seem to work with multiple threads (socket thread adds, GUI thread reads).