在后台线程中加载BitmapImage会导致UI线程断断续续

时间:2015-05-11 08:03:44

标签: c# wpf multithreading xaml

我有一些代码在后台加载BitmapImage,冻结它,并将其发送到UI线程。但是,即使没有发送到UI线程,将JPG加载到BitmapImage中的行为也会导致UI口吃,即使它发生在后台线程上。

在阅读有关BitmapImage的内容时,似乎情况可能就是即使在后台线程中,BitmapImage也会使用Dispatcher,因此在UI线程中至少运行部分加载过程。

这对我的动画功能来说是个坏消息,因为它在后台加载图像时会停顿不前。就我的代码而言,在UI线程中运行的唯一一点是将Image上的'Source'属性设置为BitmapImage。

所以,简单的问题是,如何在不触及UI线程的情况下将JPG加载到BitmapImage中?

BitmapImage bi = null;

bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(path, UriKind.Absolute);
bi.DecodePixelWidth = 250;
bi.EndInit();

bi.Freeze();

(recv as UIElement).Dispatcher.Invoke(new Action(() =>
{
    Debug.WriteLine(path + " GOT IMAGE FROM IMAGE");
    recv.recieveBitmap(bi);
}), DispatcherPriority.Input);

Action a = () => processImage(p);
Task t = new Task(a);

_jobs.Add(t);

t.Start();

1 个答案:

答案 0 :(得分:1)

在后台线程中加载BitmapImage的一种可能更有效的方法是从FileStream加载它,而不是设置其UriSource属性。

var bi = new BitmapImage();

using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    bi.BeginInit();
    bi.DecodePixelWidth = 250;
    bi.CacheOption = BitmapCacheOption.OnLoad;
    bi.StreamSource = stream;
    bi.EndInit();
}

bi.Freeze();