Using .NET 4.0, I have a Host application that parses a csv file, objectizes each row of data, and returns it as a type back to my client via a WCF callback. This part works fine. Where I start to run into trouble is when I try to add that type or collection of types to my ObservableCollection in the MainWindow.
So this...
public class MyServiceCallback : IMyServiceCallback
{
//List<Location.LocationData> lastData = new List<Location.LocationData>();
//Dictionary<string, Location.LocationData> lastData = new Dictionary<string,Location.LocationData>();
//Network exposed Callback method which recieves Host/Client common data type
//Note: Ought to be an interface and not a class type, but not needed for a small project
public void OnCallback(Location.LocationData[] t)
{
//if(t.Where(x=>x.Frequency == lastData[
//foreach (Location.LocationData d in t)
//{
// lastData.Add(d.Frequency, d);
//}
//Call static method on MainWindow to pass the collection of LocationData to UI bound LocationList
if(!(t.Length == 0))
Client.MainWindow.SetLocationList(t.ToList());
}
}
gets invoked from the WCF Host and SetLocation(t.ToList()) calls this...
public partial class MainWindow : Window
{
private static MTObservableCollection<Location.LocationData> locationList = new MTObservableCollection<Location.LocationData>();
public static MTObservableCollection<Location.LocationData> LocationList
{
get { return locationList; }
set { locationList = value; }
}
public static void SetLocationList(List<Location.LocationData> hostPushedLocationData)
{
//Clear previous location data
LocationList.Clear();
System.Threading.Thread.SpinWait(1);
//Add the pushed data to the bound collection to be displayed
hostPushedLocationData.ForEach(data => { LocationList.Add(data); System.Threading.Thread.SpinWait(1); });
}
}
If I were using a plain ObservableCollection, this wouldn't work at all because I wouldn't be able to update the collection from the WCF thread.
If I extend ObservableCollection with this...
public class MTObservableCollection<T> : ObservableCollection<T>
{
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler CollectionChanged = this.CollectionChanged;
if (CollectionChanged != null)
foreach (NotifyCollectionChangedEventHandler nh in CollectionChanged.GetInvocationList())
{
DispatcherObject dispObj = nh.Target as DispatcherObject;
if (dispObj != null)
{
Dispatcher dispatcher = dispObj.Dispatcher;
if (dispatcher != null && !dispatcher.CheckAccess())
{
dispatcher.BeginInvoke(
(Action)(() => nh.Invoke(this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))),
DispatcherPriority.DataBind);
continue;
}
}
nh.Invoke(this, e);
}
}
}
which I found here: Where do I get a thread-safe CollectionView?
I intermittently get this error:
I am getting an exception using this version, but not when using the version provided by Jonathan. Does anyone have ideas why this is happening? Here is my InnerException: This exception was thrown because the generator for control 'System.Windows.Controls.DataGrid Items.Count:3' with name 'OrdersGrid' has received sequence of CollectionChanged events that do not agree with the current state of the Items collection. The following differences were detected: Accumulated count 2 is different from actual count 3. [Accumulated count is (Count at last Reset + #Adds - #Removes since last Reset)
which is mentioned in the linked post.
I also, more often, have gotten this error: Index was out of range.
If anybody could help or point me in the right direction on what I need to do to this collection extension to solve this problem, I would greatly appreciate it. Also, would this problem be mitigated if I used .NET 4.5 instead of 4.0?
Thanks a ton!