我正在使用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“已完成”功能启动之前,我可以在Vs2008的输出窗口中看到生成了异常。它看起来像:
A first chance exception of type 'System.NotSupportedException' occurred in PresentationCore.dll
生成的异常数等于要生成的缩略图数。
使用“反复试验”方法我已将问题隔离到: BitmapFrame.Create(BI)
删除该行(使我的函数无效)也会删除异常。
我没有找到任何解释,或者在后台线程中创建缩略图的更好方法。
答案 0 :(得分:1)
Lasse,我相信问题的出现是因为您正在UI线程之外执行需要在UI线程内完成的操作。我认为,创建UI元素(BitmapImage,BitmapFrame)并添加到UI容器应该在UI线程上完成。 (如果我在这里错了,有人纠正我。)
有几种方法可以在UI线程上创建这些元素,而不会在过长的时间内阻止应用程序。最简单的可能是使用BackgroundWorker的ProgressChanged事件。在UI线程上调用ProgressChanged,这使它非常适合这种情况。
您可以使用worker的ProgressChanged事件并将其传递给在UserState参数中加载缩略图所需的路径。
答案 1 :(得分: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元素..并且工作得很好。 谢谢。 //拉塞