2009-06-29 7 views
0

J'ai créé des BitmapFrames sur un thread autre que le thread d'interface utilisateur principal; Parfois, après leur création (et la fin de leur thread créateur), j'essaie de les utiliser dans le thread principal, en tant que sources de certains contrôles Image. MAIS j'obtiens ce InvalidOperationException: Le thread appelant ne peut pas accéder à cet objet parce qu'un thread différent le possède.WPF, BitmapFrames et question d'interfonctionnement

Besoin d'aide, comment puis-je accéder (et les utiliser) à partir du fil de discussion?

Je ne vois pas comment je peux utiliser Dispatcher.Invoke depuis la fin du second thread.

Merci à l'avance.

Répondre

2

Il y a deux choses que vous devez vous assurer:

  1. le gel BitmapFrame en appelant BitmapFrame.Freeze(). Cela transforme le cadre en lecture seule et le rend disponible aux autres threads. Vous pouvez déjà faire ceci: pour informer le thread de l'interface utilisateur que le cadre est prêt, utilisez Dispatcher.Invoke, au lieu de définir les propriétés ou d'appeler directement les méthodes des objets UI.

Pour répondre à la question de Teodor, la congélation pourrait échouer si le BitmapFrame est encore en cours de modification. Cela semble se produire lorsque vous utilisez BitmapFrame.Create (Uri). Le code suivant apparaît pour éviter le problème en utilisant un décodeur. Si vous créez votre BitmapFrame différemment, la règle générale est que vous devez le laisser finir l'initialisation, le téléchargement, le décodage ou tout autre changement avant de le geler. Déconnectez toutes les liaisons aussi.

Window1.xaml

<Window x:Class="BitmapFrameDemo.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <Image Name="image"/> 
    </Grid> 
</Window> 

Window1.xaml.cs

using System; 
using System.Threading; 
using System.Windows; 
using System.Windows.Media.Imaging; 
using System.Windows.Threading; 

namespace BitmapFrameDemo { 
    public partial class Window1 : Window { 
     private Thread  thread  = null; 
     private Dispatcher dispatcher = null; 

     private void ThreadMain() { 
      PngBitmapDecoder decoder = new PngBitmapDecoder(
       new Uri("http://stackoverflow.com/content/img/so/logo.png"), 
       BitmapCreateOptions.None, 
       BitmapCacheOption.Default); 
      BitmapFrame  frame  = decoder.Frames[0]; 
      BitmapFrame  frozen  = (BitmapFrame) frame.GetAsFrozen(); 
      dispatcher.Invoke(
       new Action(() => { image.Source = frozen; }), 
       new object[] { }); 
     } 

     public Window1() { 
      InitializeComponent(); 

      dispatcher = Dispatcher.CurrentDispatcher; 
      thread = new Thread(new ThreadStart(this.ThreadMain)); 
      thread.Start(); 
     } 
    } 
} 
+0

Thanx pour la réponse! J'ai essayé la première option, mais j'ai l'erreur: Ce Freezable ne peut pas être gelé. Toute aide avec ça? – Teodor