2016-04-13 31 views
5

私のシナリオでは、バックグラウンドタスクでレンダリングする前に、変更していないBitmapCacheBrushをフリーズする必要があります。残念ながら、「このFreezableはフリーズできません」というエラーが表示されます。 フリーズ可能なオブジェクトでも、回避策やハッピーな方法でフリーズすることはできますか? この目標に達するには、リフレクションによって適切なプロパティを設定することは可能でしょうか?皆さん、事前にありがとうございます。フリーズすることができないオブジェクトをフリーズする方法

編集:(私のサンプルコードの要求に応じて)

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; 
    } 

} 
+23

これまでのところ私のお気に入りの質問タイトルだと思います。 –

+0

私はC#と友人は何も知りませんが、タイトルはそんなに素晴らしい謎です!それはウッドチャックの事を打ち負かす。そしてその精神に沿って、答えは「あなたは冷凍できない凍結可能な物体を凍結することはできません! – SergeyA

+2

Elsaに助けを求める:) – Guy

答えて

4

まず、あなたはそれを凍結することができない理由を把握する必要があります。レジストリに入り、ManagedTracingを1に設定します(作成する必要がある場合は、REG_DWORDタイプです)。 regeditのお気に入りに追加して、オン/オフを切り替える必要があるときにすばやくアクセスできるようにすることをお勧めします。

HKEY_CURRENT_USER \ソフトウェア\マイクロソフト\トレース\ WPF \ ManagedTracing

あなたがBitmapCacheBrushを凍結またはブール値プロパティBitmapCacheBrush.CanFreezeをチェックしようとすると、視覚的に出力]タブで警告が表示されます問題が何であるかを伝えるスタジオ

は私が https://blogs.msdn.microsoft.com/llobo/2009/11/10/new-wpf-features-cached-composition/

からテストケースオフに基づいてコードを作って、それが私に与えた警告があった。

System.Windows.Freezable警告:2:CanFreezeはfalseを返しているので、上のDependencyProperty Freezableには、スレッド親和性を持つ DispatcherObjectという値があります。 Freezable = 'System.Windows.Media.BitmapCacheBrush'; Freezable.HashCode = '29320365'; Freezable.Type = 'System.Windows.Media.BitmapCacheBrush'; DP = '目標'; DpOwnerType = 'System.Windows.Media.BitmapCacheBrush'; 値= 'System.Windows.Controls.Image'; Value.HashCode = '11233554'; Value.Type =「System.Windows.Controls.Image」

BitmapCacheBrush.Targetタイプの視覚的であり、全てのビジュアルはDispatcherObjectから誘導さDependencyObjectから誘導されます。そしてDispatcherObjectから派生させてhttps://msdn.microsoft.com/en-us/library/ms750441(v=vs.100).aspx#System_Threading_DispatcherObject

によると、あなたは STA挙動を有するCLRオブジェクトを作成し、作成 時にディスパッチャへのポインタを与えられます。

したがって、すべてのビジュアルはSTAです。つまり、BitmapCacheBrushをTargetに設定しない限り、BitmapCacheBrushをフリーズできません。

関連する問題