Hello,
I have an uncatchable fatal exception when sometimes I was trying to apply a Filter to a XamPivotGrid, the message was "The given key was not found in the dictionary". I have attached the stack trace in the attachement, can you urgently look into this? Thank you!
Regards
Hello Andrew,
Thank you very much for what you have done, I really appreciate it. What I was suggesting is that since LevelLevelDescriptors dictionary is accessible to several threads, we should securize the access to it. I think a simple lock would greatly improve ths stability. We will see what the dev team of XamPivotGrid has to say. Thank you.
Hello pebg,
Thank you for the additional information you have provided on this matter.
While I am still a bit skeptical about this truly being a threading issue, I have run this past our development teams that head the XamPivotGrid, and they believe that I should log this as a development issue for our engineers to investigate further. The development issue ID for this is 229422. I have created a support case for you so that you can track the status of this development issue, which you can view here after signing into your account on the Infragistics website. This support case has an ID of CAS-178406-Z1Z7V2, and I will be sending an initial update to it shortly.
Please let me know if you have any other questions or concerns on this matter.
Sincerely,AndrewAssociate Developer
Sorry I have to correct myself concerning "each calling to BuildMembers call from a different thread", they might actually come from the same thread, but the pb is that they are all in a different thread that does "BuildDimensions"
Hi Rob,
Thank you for your reply, I understand your doubt, I myself asked the same question: every time we call CreateLevelAndMetadata, we have inserted the level into LevelLevelDescriptors dictionary. But I do confirm that the line that throws not keys found exception is this line inside CreateLevelAndMetadat:
HierarchyLevelDescriptor levelDescriptor = this.LevelLevelDescriptors[level];
I have had, like you suggested, added the concerning projects into our real project solution and replaced the dll references into project references, and I sometimes had not key found exception in the line above. And then the application crashes.
My guess is that this is still a multi threading problem:
In the method "BuildDimensions" of FlatDataModelProvider.cs, we set the LevelLevelDescriptors to a new dictionary in this line:
this.LevelLevelDescriptors = new Dictionary<ILevel, HierarchyLevelDescriptor>();
While in BuildMembers we try to consume this dictionary. We only call one time BuildDimensions after setting ItemsSource of FlatDataSource, and BuildMembers can be called several times depending on the variable "savedHierarchyNames" in the method "StartCreatingFilters" inside DataSourceSnapshot.cs, and each calling to BuildMembers call from a different thread, since it's asynchrome.
Here is how it might happen:
After we have setted the ItemsSource, on the event ItemsSourceChanged inside FlatDataSettings.cs, we try to Load measures and dimensions, this is done in the same thread when we do, in this line of our method "RefreshDataSource": ItemsSource = dataSourceItems;
To remind you, we have a simple method called RefreshDataSource which just set the ItemsSource of FlatDataSource and then do a LoadCustomizations afterwards, here's the method:
public void RefreshDataSource(IEnumerable<T> dataSourceItems) { var layout = this.SaveCustomizations(); ItemsSource = dataSourceItems; this.LoadCustomizations(layout); }
So after settings ItemsSource, we do "this.LoadCustomizations", which calls "BeginRestor" inside DataSourceSnapshot.cs, which then calls "CreateFilterViewModelsFromSavedHierarchies" and then finally "StartCreatingFilters" inside DataSourceSnapshot.cs. But attention, "StartCreatingFilters' is done in another thread, which then calls several times "BuildMembers" of FlatDataModelProvider.cs which consumes LevelLevelProvider dictionary,
Since BuildDimensions and StartCreatingFilters are two parallel calls in different threads, it can happen that calling to BuildDimensions can happen between 2 calls to BuildMembers, just after one calling to BuildMembers has inserted into LevelLevelDescriptors the level it needs: it means that just after inside the method "BuildMembers" has inserted the level, the BuildDimensions reinitialized the LevelLevelDescriptors dictionary to a new dictionary, and then BuildMembers calls "CreateLevelAndMetadata", and then finally keys not found exception. My suggestion is to securized the access of "LevelLevelDescriptors" by a lock, since it's accessible to several threads. Can you try to continue this piste and give me a feedback to how you advance? Thank you very much!
Hi pebg,
Are you positive that that line is where it is crashing? Did you run your application against the source code and it broke on that line?
It's weird because before it calls CreateLevelAndMetadata() inside BuildMembers() it adds the level to the LevelLevelDescriptors dictionary. So the ILevel should be in there. Maybe it is the DimensionsInfo Dictionary instead? If you haven't already, please build the pivot grid source code and run your application against those built assemblies. When it crashes it should break on the problem line.
Also, something you can try doing is setting ItemsSource to null first before assigning it to the collection. I don't know if that will help at all but you might as well try it. This can help reset some internal states of the FlatDataSource.