【问题标题】:Load BitmapImage in background thread causes UI thread to stutter在后台线程中加载 BitmapImage 会导致 UI 线程卡顿
【发布时间】:2015-05-11 08:03:44
【问题描述】:

我有一段代码在后台加载 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();

【问题讨论】:

  • 我们可以看看你尝试了什么吗?
  • 好的,我已经在原始帖子中添加了一些代码,除了“调用”之外的所有内容都在后台线程中,作为任务运行。
  • 您是否每帧都触发这些任务?你能包含一些关于循环的代码吗?
  • 另外,请注意任务不一定在另一个线程上运行。你是如何开始这项任务的?
  • 不是每一帧,基本上,定时器都会运行并告诉我的应用程序每秒更新大约 30 次,在第一次更新时,图像被加载,它们在动画中从屏幕上掉下来,当它们离开屏幕底部,图像被新图像替换。在加载新的图像时,我的 UI 会卡顿,如果我简单地将图像移回屏幕顶部,整个事情就会顺利运行。我将编辑原件以显示我如何启动任务。

标签: c# wpf multithreading xaml


【解决方案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();

【讨论】:

  • 感谢您的提示,刚刚试了一下,我看不出有什么不同。
猜你喜欢
  • 2010-12-21
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多