How to freeze frozen objects that cannot be frozen

In my scenario, I want to freeze an immutable BitmapCacheBrush before I want to display it in a background job. Unfortunately, I get the error "This Freezable could not be frozen." Is there a workaround or hacker way to freeze and not freeze objects? Maybe you can set the right properties through reflection in order to achieve this goal? Thanks guys in advance.

Edit: (My sample code is on request)

public static class ext { public static async Task<BitmapSource> RenderAsync(this Visual visual) { var bounds = VisualTreeHelper.GetDescendantBounds(visual); var bitmapCacheBrush = new BitmapCacheBrush(visual); bitmapCacheBrush.BitmapCache = new BitmapCache(); // We need to disconnect the visual here to make the freezable freezable :). Of course this will make our rendering blank //bitmapCacheBrush.Target = null; bitmapCacheBrush.Freeze(); var bitmapSource = await Task.Run(() => { var renderBitmap = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32); var dVisual = new DrawingVisual(); using (DrawingContext context = dVisual.RenderOpen()) { context.DrawRectangle(bitmapCacheBrush, null, new Rect(new Point(), new Size(bounds.Width, bounds.Height))); } renderBitmap.Render(dVisual); renderBitmap.Freeze(); return renderBitmap; }); return bitmapSource; } } 
+5
source share
1 answer

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.

+4
source

Source: https://habr.com/ru/post/1247040/


All Articles