Frustrating error in WPF (.NET 4.0) internals: Hashtable insert failed. Load factor too high
Asked Answered
M

1

0

I have built custom Rules Engine, where each element of this engine is a descendant of DependencyObject class, so that it could be described in XAML including support for dependency properties, markup extensions, bindings, and so on. The purpose of this Rules Engine is to process certain information which comes as an input and to return the output information back to the queue. The entire tree of object is being instantiated once (from XAML) in a single thread and the series of Input objects are being processed from the Input queue. All works fine until I increase the number of threads - sometimes (not always!) it throws the following exception:

    System.InvalidOperationException: Hashtable insert failed. Load factor too high. The most common cause is multiple threads writing to the Hashtable simultaneously.
       at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
       at MS.Internal.Data.ValueChangedEventManager.PrivateAddListener(Object source, IWeakEventListener listener, PropertyDescriptor pd)
       at MS.Internal.Data.PropertyPathWorker.ReplaceItem(Int32 k, Object newO, Object parent)
       at MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32 k, ICollectionView collectionView, Object newValue, Boolean isASubPropertyChange)
       at MS.Internal.Data.PropertyPathWorker.OnDependencyPropertyChanged(DependencyObject d, DependencyProperty dp, Boolean isASubPropertyChange)
       at System.Windows.Data.BindingExpression.HandlePropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
       at System.Windows.Data.BindingExpressionBase.OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
       at System.Windows.Data.BindingExpression.OnPropertyInvalidation(DependencyObject d, DependencyPropertyChangedEventArgs args)
       at System.Windows.DependentList.InvalidateDependents(DependencyObject source, DependencyPropertyChangedEventArgs sourceArgs)
       at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
       at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
       at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
       at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
...

So I wonder, is this a bug in WPF internals or I have to take a closer look at my code? Has anyone experienced such problem before? Since I don't use any global thread-unsafe objects that may interfere with each other, I expect DependencyObject to work correctly in multi-threaded environment, correct?

Marcela answered 12/9, 2011 at 19:36 Comment(4)
Based on the HashTable Thread Safety section you should be okay to have multiple readers and a single writer. The real question is are you only writing to this DependecyObject from 1 location and what thread is that object associated with?Choiseul
Yes I am manipulating with DependencyObject's properties from the same thread it was created in. There is no even multiple readers from different threads - all reading/writings are done in the same thread!Marcela
I don't believe it is a problem with the DependecyObject not functioning in a multithreaded environment, but the expectation that HashTable will allow multiple inserts. There are a few SO questions about the issue you see (not related to DependecyObject), but it boils down to making your .Insert(...) calls safe. #505822 It might be worth trying to put a thread sync mechanism around the inserts such as Lock(...) to see if you can avoid this deadlock.Choiseul
As I mentioned in my other comment, I don't have much control over the Dependency Properties given the fact that I assign values using Bindings in XAML. I suspect that DependencyObject internally uses some centralized storage for keeping its values - perhaps it is not entirely thread safe?Marcela
S
0

Try using a lock() statement around every write to make sure that your writes are not happening simultaneously.

Shaikh answered 12/9, 2011 at 20:30 Comment(1)
Well, I cannot do this because the whole purpose of using Dependency Properties in my case is to be able to automatically bind them to a source object in XAML. If you look at the stack frame above, error occurs after: System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value), and I have no control over it...Marcela

© 2022 - 2024 — McMap. All rights reserved.