I have my own rule engine in which each element of this engine is a descendant of the DependencyObject
class, so it can be described in XAML, including support for dependency properties, markup extensions, bindings, etc. The purpose of this rule mechanism is to process certain information that comes in the form of input and return of output information to the queue. The entire object tree is created once (from XAML) in one thread, and a series of input objects is processed from the input queue. Everything 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, interestingly, is this a bug in WPF internals, or do I need to look more closely at my code? Has anyone encountered this problem before? Since I do not use any global unsafe objects that can interfere with each other, I expect DependencyObject to work correctly in a multi-threaded environment, fix it?