2012-06-12 162 views
4

我正在加載大量圖像並將其顯示爲縮略圖的C#WPF應用程序。我想用多線程的方式來完成它。所以我試圖實現一個BackgroundWorker。在C#中加載異步圖像#

BackgroundWorker的的DoWork的()的代碼:

string[] files = e.Argument as string[]; 
foreach (string file in files) 
{ 
    ImageModel image = new ImageModel(); 
    image.FilePath = file; 
    _importWorker.ReportProgress(1, image); 
    _imageCollectionVM.Images.Add(image); // also tried this one in ReportProgress() 
} 

在我的XAML代碼我綁定到ImageModel的BitmapImage的財產。 (AsyncState = True並沒有幫助。)在這裏我得到這個錯誤:「DependencySource」和「DependencyObject」必須在同一個線程中。

<Image Source="{Binding BitmapImage}" /> 

如果我發表評論,圖片似乎已被導入,但我無法訪問它,例如,通過在ListView中選擇它。在它的SelectionChanged中它表示這個對象被另一個線程擁有。

我該如何解決這些問題?提前致謝!

回答

1

後臺工作是好的海事組織大任務,但如果它像你所說的那樣簡單E完成我寧願與圖片

List<Image> Images =new List<Image>(); 

的列表,像這樣做

啓動,然後運行該

Task.Factory.StartNew(() => 
{ 
    string[] files = e.Argument as string[]; 
    foreach (string file in files) 
    { 
     ImageModel image = new ImageModel(); 
     image.FilePath = file; 
     // _importWorker.ReportProgress(1, image); 

     this.BeginInvoke(new Action(() => 
     { 
      Images.Add(image); 
     })); 
    } 
}); 

不保證我在代碼括號權數。

+0

我想我必須使用'this.Dispatcher'的'BeginInvoke'方法,對嗎?實際上,我已經有一個ObservableCollection,我將ListView的項目源(已更新的原始帖子)綁定到該ObservableCollection。但是如果我在'Action內執行'imageCollectionVM.Images.Add(image)',我得到了「DependencySource和DependencyObject應該在同一個線程中」的錯誤信息。 – Sentropie

+0

如果您正在嘗試使用ObservableCollection,請參閱我在答案中發佈的最後一個鏈接,它具有可從後臺線程更新的BindingList <> –

2

您必須將對GUI的更新集中到主線程。基本上你只能多線程加載磁盤上的映像,但GUI的實際更新必須單線程完成。

有很多方法可以做到這一點,並在stackoverflow許多問題解決它。這裏有一些讓你開始

Update UI from background Thread

Update BindingList<> from a background Thread?

Is it evil to update a pictureBox from a background C# thread?

如何使用的BindingList這個

How do you correctly update a databound datagridview from a background thread

0

在類似的情況下,我做了以下內容:

  • 創建ImageProvider類,實際上做的圖像加載工作
  • 讓圖像綁定到一個ImageSource的視圖模型在我ItemViewModel
  • 讓這個ImageSource的偷懶

    // // 這裏的僞

    Lazy lazy = new Lazy(imageProvider.LoadImage(this.imagePath))

    //在ImageViewModel中...

    imageSource {get {return lazy.Value; }}

+0

ImageProvider類將使用多線程還是以如何保護GUI冷凍? – Sentropie

+0

在我的情況下,imageprovider沒有在UI線程中運行。也許這裏是一些工作要做的這個例子 –

+0

@Sentropie:兩個步驟來採取這裏解耦它的權利,我相信。 –