2009-06-29 56 views
0

我有一些在主UI線程以外的線程上創建的BitmapFrame; 有些時候它們被創建後(以及它們的創建者線程完成),我試圖在主線程中使用它們作爲某些Image控件的源代碼。WPF,BitmapFrames&cross-threading問題

但是我得到這個InvalidOperationException:調用線程不能訪問這個對象,因爲一個不同的線程擁有它。

需要一些幫助,我如何從主線程訪問(並使用)它們?

因爲第二個線程完成,所以我沒有看到如何使用Dispatcher.Invoke。

預先感謝您。

回答

2

有兩件事情你必須確保:

  1. 通過調用BitmapFrame.Freeze凍結BitmapFrame()。這將框架變爲只讀,並使其可用於其他線程。

  2. 您可能已經這樣做了:要讓UI線程知道框架已準備就緒,請使用Dispatcher.Invoke,而不是直接設置屬性或調用UI對象的方法。

要回答Teodor的問題,如果BitmapFrame仍在更改中,凍結可能會失敗。這似乎發生在使用BitmapFrame.Create(Uri)時。下面的代碼似乎通過使用解碼器來避免該問題。如果你以不同的方式創建你的BitmapFrame,一般的規則是你必須讓它在完成初始化,下載,解碼或者其他更改之前凍結它。斷開任何綁定。

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的答覆! 我試過第一個選項,但是我得到錯誤:這個Freezable不能被凍結。有什麼幫助嗎? – Teodor 2009-06-30 14:47:42