1

WPFBackgroundWorkerを使用してサムネイルを作成しています。私のワーカー関数は次のようになります。

private void work(object sender, DoWorkEventArgs e)
{ 
  try
  {
    var paths = e.Argument as string[];
    var boxList = new List<BoxItem>();
    foreach (string path in paths)
    {                   
       if (!string.IsNullOrEmpty(path))
       {
        FileInfo info = new FileInfo(path);
        if (info.Exists && info.Length > 0)
        {
           BitmapImage bi = new BitmapImage();
           bi.BeginInit();
           bi.DecodePixelWidth = 200;
           bi.CacheOption = BitmapCacheOption.OnLoad;
           bi.UriSource = new Uri(info.FullName);
           bi.EndInit();
           var item = new BoxItem();
           item.FilePath = path;
           MemoryStream ms = new MemoryStream();
           PngBitmapEncoder encoder = new PngBitmapEncoder();
           encoder.Frames.Add(BitmapFrame.Create(bi));  
           encoder.Save(ms);
           item.ThumbNail = ms.ToArray();
           ms.Close();
           boxList.Add(item);
        }
      }
    }
    e.Result = boxList;
  }
  catch (Exception ex)
  { 
    //nerver comes here
  }
}

この関数が終了し、BackgroundWorkerの「完了」関数が開始される前に、Vs2008の出力ウィンドウで例外が生成されていることがわかります。次のようになります。

 A first chance exception of type 'System.NotSupportedException' occurred in PresentationCore.dll

生成される例外の数は、生成されるサムネイルの数と同じです。

「試行錯誤」の方法を使用して、問題を次のように分離しました:BitmapFrame.Create(bi)

その行を削除すると(私の関数が役に立たなくなります)、例外も削除されます。

これについての説明や、バックグラウンドスレッドでサムネイルを作成するためのより良い方法は見つかりませんでした。

4

2 に答える 2

1

Lasse さん、UI スレッド内で実行する必要があるアクションを UI スレッド外で実行しているため、問題が発生すると思います。UI 要素 (BitmapImage、BitmapFrame) の作成と UI コンテナーへの追加は、UI スレッドで行う必要があると思います。(私がここで間違っている場合は、誰かが私を訂正してください)。

アプリケーションを長時間ブロックせずに UI スレッドでこれらの要素を作成する方法はいくつかあります。おそらく最も簡単な方法は、BackgroundWorker の ProgressChanged イベントを使用することです。ProgressChanged は UI スレッドで呼び出されるため、この状況に最適です。

ワーカーの ProgressChanged イベントを使用して、サムネイルをロードするために必要なパスを UserState 引数に渡すことができます。

于 2010-03-18T13:24:29.927 に答える
0

ご意見ありがとうございます。別の解決策を探し始め、これを思いつきました。

       try
        {
            var paths = e.Argument as string[];
            var boxList = new List<BoxItem>();

            foreach (string path in paths)
            {
                using (Image photoImg = Image.FromFile(path))
                {
                    int newWidth = 200;
                    int width = newWidth;
                    int height = (photoImg.Height * newWidth) / photoImg.Width;

                    var thumbnail = new Bitmap(width, height);

                    using (Graphics g = Graphics.FromImage((System.Drawing.Image)thumbnail))
                    {
                        g.DrawImage(photoImg, 0, 0, width, height);
                        using (var ms = new System.IO.MemoryStream())
                        {
                            var item = new BoxItem();
                            item.FilePath = path;

                            thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

                            item.ThumbNail = ms.ToArray();
                            boxList.Add(item);
                        }
                    }
                }
            }
            e.Result = boxList;
        }

        catch (Exception exp)
        {
        } 

UI要素を使用していません..うまく機能します。ありがとう。//ラッセ

于 2010-03-18T21:05:05.427 に答える