2012-06-12 160 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:两个步骤来采取这里解耦它的权利,我相信。 –