1

I am getting error reports from users who are logging in remotely to application. The app works fine until when they come back to the office and log directly to their desktops - the app crashes and the error report is a standard 'Freezable cannot be frozen' but none of the known workarounds are fixing this one.

Every single Brush resource in the app is decorated with ice:Freeze:

<SolidColorBrush ice:Freeze="true" 

Also the exception is thrown as a domain unhandled exception so there is now way to swallow it.

Over the last couple of months I spent hours analyzing reported issues with Freezables bot cannot find any solution.

.NET code where the problem happens:

    /// <summary>
    ///     Unbinds a Freezable from its Context.
    /// </summary>
    /// <param name="resource">The resource to freeze.</param>
    private static void Freeze(object resource)
    {
        Freezable freezable = resource as Freezable;
        if (freezable != null && !freezable.IsFrozen)
        {
            freezable.Freeze();
        }
    }

    /// <summary>
    ///     Searches for a resource inside a ResourceDictionary.
    /// </summary>
    /// <param name="key">The original key.</param>
    /// <param name="typeKey">The key cast to Type.</param>
    /// <param name="resourceKey">The key cast to ResourceKey.</param>
    /// <param name="isTraceEnabled">Tracing on/off.</param>
    /// <param name="allowDeferredResourceReference">
    ///     If this flag is true the resource will not actually be inflated from Baml.
    ///     Instead we will return an instance of DeferredDictionaryReference which
    ///     can later be used to query the resource
    /// </param>
    /// <param name="mustReturnDeferredResourceReference">
    ///     If this method is true this method will always return a
    ///     DeferredThemeResourceReference instance which envelopes the underlying resource.
    /// </param>
    /// <param name="canCache">Whether callers can cache the value.</param>
    /// <returns></returns>
    private static object FindDictionaryResource(
        object      key,
        Type        typeKey,
        ResourceKey resourceKey,
        bool        isTraceEnabled,
        bool        allowDeferredResourceReference,
        bool        mustReturnDeferredResourceReference,
        out bool    canCache)
    {
        // Thread safety handled by FindResourceInternal. Be sure to have locked _resourceCache.SyncRoot.

        Debug.Assert(typeKey != null || resourceKey != null, "typeKey or resourceKey should be non-null");

        canCache = true;
        object resource = null;
        Assembly assembly = (typeKey != null) ? typeKey.Assembly : resourceKey.Assembly;

        if ((assembly == null) || IgnoreAssembly(assembly))
        {
            // Without an assembly, we can't figure out which dictionary to look at.
            // Also, ignore some common assemblies we know to not contain resources.
            return null;
        }

        ResourceDictionaries dictionaries = EnsureDictionarySlot(assembly);
        ResourceDictionary dictionary = dictionaries.LoadThemedDictionary(isTraceEnabled);
        if (dictionary != null)
        {
            resource = LookupResourceInDictionary(dictionary, key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache);
        }

        if (resource == null)
        {
            dictionary = dictionaries.LoadGenericDictionary(isTraceEnabled);
            if (dictionary != null)
            {
                resource = LookupResourceInDictionary(dictionary, key, allowDeferredResourceReference, mustReturnDeferredResourceReference, out canCache);
            }
        }

        if (resource != null)
        {
            // Resources coming out of the dictionary may need to be frozen
            Freeze(resource);
        }

        return resource;
    }

System.InvalidOperationException: This Freezable cannot be frozen. at System.Windows.Freezable.Freeze() at System.Windows.SystemResources.Freeze(Object resource) at System.Windows.SystemResources.FindDictionaryResource(Object key, Type typeKey, ResourceKey resourceKey, Boolean isTraceEnabled, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, Boolean& canCache) at System.Windows.SystemResources.FindResourceInternal(Object key, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference) at System.Windows.FrameworkElement.FindResourceInternal(FrameworkElement fe, FrameworkContentElement fce, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, Boolean isImplicitStyleLookup, Object& source) at System.Windows.StyleHelper.GetChildValueHelper(UncommonField1 dataField, ItemStructList1& valueLookupList, DependencyProperty dp, DependencyObject container, FrameworkObject child, Int32 childIndex, Boolean styleLookup, EffectiveValueEntry& entry, ValueLookupType& sourceType, FrameworkElementFactory templateRoot) at System.Windows.StyleHelper.GetChildValue(UncommonField1 dataField, DependencyObject container, Int32 childIndex, FrameworkObject child, DependencyProperty dp, FrugalStructList1& childRecordFromChildIndex, EffectiveValueEntry& entry, ValueLookupType& sourceType, FrameworkElementFactory templateRoot) at System.Windows.StyleHelper.GetValueFromTemplatedParent(DependencyObject container, Int32 childIndex, FrameworkObject child, DependencyProperty dp, FrugalStructList1& childRecordFromChildIndex, FrameworkElementFactory templateRoot, EffectiveValueEntry& entry) at System.Windows.FrameworkElement.GetValueFromTemplatedParent(DependencyProperty dp, EffectiveValueEntry& entry) at System.Windows.FrameworkElement.GetRawValue(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& entry) at System.Windows.FrameworkElement.EvaluateBaseValueCore(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry& newEntry) at System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, OperationType operationType) 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.InvalidateProperty(DependencyProperty dp) at System.Windows.StyleHelper.InvalidateResourceDependentsForChild(DependencyObject container, DependencyObject child, Int32 childIndex, ResourcesChangeInfo info, FrameworkTemplate parentTemplate) at System.Windows.TreeWalkHelper.InvalidateStyleAndReferences(DependencyObject d, ResourcesChangeInfo info, Boolean containsTypeOfKey) at System.Windows.TreeWalkHelper.OnResourcesChanged(DependencyObject d, ResourcesChangeInfo info, Boolean raiseResourceChangedEvent) at System.Windows.TreeWalkHelper.OnResourcesChangedCallback(DependencyObject d, ResourcesChangeInfo info) at System.Windows.DescendentsWalker1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren) at System.Windows.DescendentsWalker1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren) at System.Windows.DescendentsWalker1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren) at System.Windows.DescendentsWalker1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren) at System.Windows.DescendentsWalker1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren) at System.Windows.DescendentsWalker1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker1._VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.VisitNode(FrameworkElement fe) at System.Windows.DescendentsWalker1.VisitNode(DependencyObject d) at System.Windows.DescendentsWalker1.WalkLogicalChildren(FrameworkElement feParent, FrameworkContentElement fceParent, IEnumerator logicalChildren) at System.Windows.DescendentsWalker1.WalkFrameworkElementLogicalThenVisualChildren(FrameworkElement feParent, Boolean hasLogicalChildren) at System.Windows.DescendentsWalker1.IterateChildren(DependencyObject d) at System.Windows.DescendentsWalker`1.StartWalk(DependencyObject startNode, Boolean skipStartNode) at System.Windows.TreeWalkHelper.InvalidateOnResourcesChange(FrameworkElement fe, FrameworkContentElement fce, ResourcesChangeInfo info) at System.Windows.SystemResources.InvalidateTreeResources(Object args) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)

  • Did freezing your `Brush` resources really make a noticeable difference in performance? – Sheridan Aug 18 '14 at 10:07
  • I did freeze the brushes to possibly fix the 'Freezable cannot be frozen' issue. There is no big difference in performance. – tomasz_kajetan_stanczak Aug 18 '14 at 10:22
  • Freezing `Brush`es is *not* going to help to solve a problem about a *`Freezable` cannot be frozen* issue. – Sheridan Aug 18 '14 at 10:25
  • I suppose it was an act of desperation. Any ideas what would solve it? – tomasz_kajetan_stanczak Aug 18 '14 at 10:27
  • Not unless I knew what was causing it. – Sheridan Aug 18 '14 at 10:32
  • I experience the same problem – yatskovsky Apr 18 '17 at 15:56
  • Is this in a multi-threaded WPF application? Because the WPF code sure looks like it could suffer from a race condition, if the freezeable is frozen in a separate thread between the call to `IsFrozen` and `Freeze()`. We've seen this with customers who are using multiple WPF threads. – Sebastian Apr 13 '18 at 12:56
  • Yes it was multithreaded and the problem was only when users were logged in remotely and after that were continuing the session locally. This one we never managed to get rid off. It was very annoying but not critical beyond the significant amount of time we spent trying to fix it. – tomasz_kajetan_stanczak Jun 13 '18 at 15:39

0 Answers0