4

たくさんの画像を読み込んでサムネイルとして表示するC#WPFアプリケーションに取り組んでいます。マルチスレッドでやりたいです。したがって、BackgroundWorkerを実装しようとしました。

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で、このオブジェクトは別のスレッドによって所有されていると示されています。

これらの問題を解決するにはどうすればよいですか?前もって感謝します!

4

3 に答える 3

2

GUIの更新をメインスレッドにマーシャリングする必要があります。基本的に、ディスクからのイメージのロードはマルチスレッドでのみ実行できますが、GUIの実際の更新はシングルスレッドで実行する必要があります。

これを行うには多くの方法があり、stackoverflowに関する多くの質問がそれに対処します。ここにあなたが始めるためのいくつかがあります

バックグラウンドスレッドからUIを更新する

バックグラウンドスレッドからBindingList<>を更新しますか?

バックグラウンドのC#スレッドからpictureBoxを更新するのは悪いことですか?

これにBindingListを使用する方法

バックグラウンドスレッドからデータバインドされたdatagridviewを正しく更新するにはどうすればよいですか

于 2012-06-12T18:17:42.853 に答える
1

BackGround Workerは、大規模なタスクに適したimoですが、あなたがしているような単純なものであれば、このようにしたいと思います。

画像のリストから始めます

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);
         }));
     }
 });

そのコードに正しい数の角かっこがあるという保証はありません。

于 2012-06-12T18:22:15.053 に答える
0

同様の状況で、私は次のことを行いました。

  • 実際に画像の読み込み作業を行うImageProviderクラスを作成します
  • 画像のビューモデルをItemViewModelのImageSourceにバインドします
  • このImageSourceを怠惰にします

    ////ここに擬似コード

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

    //ImageViewModelで..。

    imageSource {get {return lazy.Value; }}

于 2012-06-12T18:22:20.340 に答える