views:

183

answers:

4

I have a database with a table that records data coming from various sources. 3 columns

'Source' 'Value' 'Timestamp'

e.g.

source1 21 '11:03'

source6 22 '11:03'

source9 456 '11:03'

The table is updated 2 to 3 times a second. Each Value may or may not change. Each 'Source' value is displayed in a seperate label or text box on the screen (not in a grid). I need to find the best method to get this data to bind to WPF contols. What type of object should I hold the data in Dictionary, DataTable etc.

What type of object is going to hold the data? How do I bind my Label or TextBox to the value.

I query the sources 2 to 4 times a second. The vast majority of the time the values in the database table won't change Often it is only one value that changes Sometimes they all change I only expect to have upto about 30 unique datasources.

Put your thinking caps on please.

+1  A: 

I'm not exactly clear on this, but it appears that the table is updated 2 to 4 times per second. Is this correct?

If so, then setting up a thread to query the table and update an in-memory collection of objects which fire off an event when updated seems like it would be a reasonable approach. If you made these objects implement INotifyPropertyChanged you could bind directly to the objects' properties, and then when they are updated in the background, the UI would be updated auotmatically (being careful about thread marshalling, of course).

codekaizen
Unless you do something special, adding or removing whole items from the collection will cause an exception.
Jonathan Allen
@Johnathan - Why add and remove items? I think updating them in place is more reasonable, if the assumption of updated vs. added data holds.
codekaizen
Yes, by all means update when possible. But what happens if your query returns 10 rows now and 11 rows next time?
Jonathan Allen
Just query all the rows to begin with. Then update. If the OP is adding rows, then I would recommend using an ICollectionView to manage adding and removing values.
codekaizen
+2  A: 

Just by chance I'm working through a very similar problem. Like me, I am assuming that you are updating the data in a background thread.

Collections

Use MTObservableCollection instead of ObservableCollection to store the data. A ObservableCollection is normally used for data binding on stuff that can change, but it can't be updated from a background thread. MTObservableCollection works for me, but it isn't inheritently thread safe so be careful.

http://www.julmar.com/blog/mark/2009/04/01/AddingToAnObservableCollectionFromABackgroundThread.aspx

Models

Each object should implement INotifyPropertyChanged Interface. This will make them support data binding. Also, WPF allows you to update properties this way on brackground threads.

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

Prefer Update over Clear and Add

Make sure you always update objects when you can. Don't just clear the collection and reload it, that will be very expensive and cause adverse UI effects. Of course you can do individual adds and removes when needed.

Jonathan Allen
A: 

Option 2 - Message Queues

Instead of updating the collections on a background thread, just create your deltas (list of changes). Pump these changes into your GUI thread using Dispatcher.BeginInvoke with a low priority level, perhaps Background or ContextIdle.

Once the dispatcher picks up your changes, it will run them on your GUI thread. This allows you to avoid all of the nasty threading implications. And by tweaking the priority level you can tune it for update speed vs. user responsiveness.

Again, make sure you use updates instead of remove and replace.

Jonathan Allen
A: 

I'd be interested to know if Reactive Extensions could help you in this situation. With them, instead of "pulling" data into your form, data can be "pushed" from the event source to update your controls. Just a thought. Hope it's helpful, or at least interesting!

Pwninstein