First, you need to find out why you cannot freeze it. Enter the registry and set ManagedTracing to 1 (if you need to do this, it is the REG_DWORD type). I suggest you add it to your Favorites in regedit so you can quickly get to it when you need to turn it on / off.
HKEY_CURRENT_USER \ SOFTWARE \ Microsoft \ Tracing \ WPF \ ManagedTracing
When you try to freeze BitmapCacheBrush or check the bool property of BitmapCacheBrush.CanFreeze, you will receive a warning on the Output tab in the visual studio, telling you what the problem is.
I made a test case based on the code https://blogs.msdn.microsoft.com/llobo/2009/11/10/new-wpf-features-cached-composition/
And the warning this gave me was:
System.Windows.Freezable Warning: 2: CanFreeze returns false because DependencyProperty on Freezable has a value that is a thread-bound DispatcherObject; Freezable = 'System.Windows.Media.BitmapCacheBrush'; Freezable.HashCode = '29320365'; Freezable.Type = 'System.Windows.Media.BitmapCacheBrush'; DP = 'Target'; DpOwnerType = 'System.Windows.Media.BitmapCacheBrush'; Value = 'System.Windows.Controls.Image'; Value.HashCode = '11233554'; Value.Type = 'System.Windows.Controls.Image'
BitmapCacheBrush.Target is of type Visual and all Visuals are produced from DependencyObject, which is obtained from DispatcherObject. And according to https://msdn.microsoft.com/en-us/library/ms750441(v=vs.100).aspx#System_Threading_DispatcherObject
Having received from DispatcherObject, you create a CLR object that has an STA, and a pointer to the dispatcher will be provided when creating the time.
So, all visual objects are STAs, which means you cannot freeze BitmapCacheBrush unless you set its Target to null.
source share