Domanda

ho sviluppato un'applicazione per catturare e salvare le immagini in un database, ma sto avendo un problema con l'utilizzo di memoria. Sul mio oggetto di dominio Ho 3 proprietà:

Immagine - matrice Byte, i contenuti sono un jpg

RealImageThumb - L'array di byte convertito in una BitmapImage e ristretto, visualizzato all'utente in un GridView con altre miniature

RealImage -. Non ha setter, l'array di byte convertito ad una sorgente bitmap, questo è mostrato in un suggerimento quando le si adagia su di esso utente

Il problema che ho è che se un utente passa sopra ogni immagine a sua volta spirali utilizzo della memoria. Mi rendo conto che come un utente si posiziona su fonti bitmap sono generati e la memoria non viene liberata, ho provato dando RealImage una struttura di supporto e l'assegnazione di questa NULL dopo ma ancora la memoria non viene liberata (attesa per la spazzatura collezionista?).

modifica:

E 'questo quello che volevi dire Ray? Non ricevo tutto quanto riportato nella descrizione come sotto, ma se provo e definire un WeakReference<BitmapImage>, ottengo lo System.WeakReference non avere errore di parametri di tipo.

  private WeakReference _realImage;
        public virtual BitmapImage RealImage
        {
            get
            {
                if (_realImage == null || _realImage.Target == null)
                {

                    if (Image == null) return null;
                    var newBitmapImage = new BitmapImage();
                    newBitmapImage.BeginInit();
                    newBitmapImage.CacheOption = BitmapCacheOption.None;
                    newBitmapImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                    newBitmapImage.StreamSource = new MemoryStream(Image);
                    newBitmapImage.EndInit();
                    _realImage = new WeakReference(newBitmapImage);
                }

                return (BitmapImage)_realImage.Target;
            }
        }
È stato utile?

Soluzione

Si avrà bisogno di fare tre cose:

  1. Nel costruire il vostro BitmapImage utilizzo StreamSource di fornire i dati. Non utilizzare UriSource o passare un Uri al costruttore, che causerebbe l'immagine da aggiungere alla cache immagine.

  2. In attuazione RealImage del vostro oggetto di dominio, memorizzare un WeakReference al BitmapImage non il BitmapImage stesso. Quando RealImage è inverosimile, se uno o WeakReference WeakReference.Target è nullo, creare un nuovo BitmapImage e un nuovo WeakReference ad esso.

  3. Usa un DataTrigger con commutazione template per includere solo il vostro controllo Image nella struttura ad albero visuale quando è visibile

Ecco i modelli necessari per la fase 3, tra cui quello con la DataTrigger:

<DataTemplate x:Key="EmptyTemplate">
</DataTemplate>

<DataTemplate x:Key="RealImageTemplate">
  <Image Source="{Binding RealImage.Target}" Width="300" Height="300" />
</DataTemplate>

<DataTemplate x:Key="RealImageWhenVisible">

  <!-- Use EmptyTemplate when I am not visible -->
  <ContentPresenter x:Name="Presenter"
                    Content="{Binding}"
                    ContentTemplate="{StaticResource EmptyTemplate}"/>

  <!-- Switch to RealImageTemplate when I am visible -->
  <DataTemplate.Triggers>
    <DataTrigger Binding="{Binding IsVisible, RelativeSource={RelativeSource Self}}"
                 Value="True">
      <Setter TargetName="Presenter"
              Property="ContentPresenter.ContentTemplate"
              Value="{StaticResource RealImageTemplate}" />
    </DataTrigger>
  </DataTemplate.Triggers>
</DataTemplate>

Ora è possibile definire la descrizione comandi in questo modo:

<Rectangle Width="40" Height="40" Fill="Blue">
  <Rectangle.ToolTip>
    <ContentPresenter Content="{Binding}"
                      ContentTemplate="{StaticResource RealImageWhenVisible}" />
  </Rectangle.ToolTip>
</Rectangle>

Come funziona: Ci sono due ContentPresenters uno dentro l'altro:

  • Quando il ContentPresenter esterno è invisibile, il ContentPresenter interno avrà EmptyTemplate quindi nessuna immagine verrà caricata.
  • Quando il ContentPresenter esterno è visibile, il ContentPresenter interno avrà RealImageTemplate modo l'immagine viene caricato e visualizzato.

Il motivo è necessario per fare questo è che una descrizione comandi può tentare di ottimizzare le prestazioni, non disponendo del popup una volta che è stato dimostrato.

Aggiorna

Il codice che avete inviato per RealImage dovrebbe funzionare, ed è quasi esattamente quello che stavo pensando. Mi sono reso conto di questa mattina non c'è davvero alcun bisogno di impostare BitmapCacheOption o BitmapCreateOption finché non viene specificato alcun SourceUri. Ho aggiornato la mia risposta per riflettere questa e anche per chiarire la cosa WeakReference. Ho anche corretto un bug nel modello: sono stato il legame con "RealImage" quando avrei dovuto essere vincolanti per "RealImage.Target"

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top