1

我正在使用 WPF BackgroundWorker 创建缩略图。我的工作函数看起来像:

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“Completed”函数启动之前,我可以在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 事件。在 UI 线程上调用 ProgressChanged,这使得它非常适合这种情况。

您可以使用工作人员的 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 元素.. 并且工作得很好。谢谢。//lasse

于 2010-03-18T21:05:05.427 回答