【问题标题】:WPF BitmapFrame and multiple threadsWPF BitmapFrame 和多线程
【发布时间】:2011-02-09 01:20:52
【问题描述】:

我有一个 PNG 文件存储在我的云中的 blob 存储中,我想下载它并在 WPF 的屏幕上呈现它。

我知道 Dispatcher 和 Freezing,但没有任何效果。我不断收到有关“另一个线程拥有它”的错误消息。

这是我所拥有的:

var decoder = GetDecoder("http://address/image.png");

Dispatcher.Invoke(DispatcherPriority.Send, new Action<BitmapFrame>(SetImage), decoder.Frames[0]);

public void SetImage(BitmapFrame source)
{
    var bitmapFrame = BitmapFrame.Create(source);  //ERROR HERE!!!!!!!!
    LazyImage.Source = bitmapFrame;
}

private BitmapDecoder GetDecoder(object uri)
{
    var extension = System.IO.Path.GetExtension((string)uri);
    BitmapDecoder decoder = null;
    if (extension.ToLower() == ".png")
        decoder = BitmapDecoder.Create(new Uri((string)uri, UriKind.Absolute), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
    return decoder;
}

如果我尝试冻结 Frame[0],我会收到一个异常,指出无法冻结该 Frame。此外,BitmapDecoder.Create 返回的解码器不是PngBitmapDecoder,而是LateBoundBitmapDecoder,我真的不知道如何有效使用。

【问题讨论】:

    标签: c# wpf multithreading bitmap


    【解决方案1】:

    简而言之:尝试将结果包装成WriteableBitmap

    Long story, with code.

    【讨论】:

    • 就我而言,这是唯一有效的解决方案。我需要将 BitmapFrame 输入到 TransformedBitmap 中。无法控制在哪个线程上创建 BitmapFrame,因为它由库提供(并且 BitmapFrame 的 Dispatcher 属性为空)。即使查询 CanFreeze 属性也会导致异常。我有两个选择:对我和其他人的源代码进行大修,或者使用 WriteableBitmap。猜猜我选择了哪一个...
    【解决方案2】:

    您可能不仅需要在调度程序上创建 Bitmapframe,还需要创建 BitmapDecoder?您是否尝试过在调度程序上调用 GetDecoder?

    【讨论】:

    • 也许,我认为解码器的创建是一个同步操作,这意味着我想避免它发生在 UI 线程上。请注意,我本地 PC 上的文件(不是 http URL)可以正常工作,因为解码器是 PngBitmapDecoder
    • 嗯...也许您可以在线程中调用 BitmapFrame.Create() 并尝试冻结它返回的帧?
    • 如果我冻结 LateBoundBitmapDecoder 返回的帧,我会得到一个异常,但如果我使用本地 URL(因此是 PngBitmapDecoder)我可以冻结它,它工作得很好。
    • 环顾四周,发现了这个:social.msdn.microsoft.com/Forums/en-US/wpf/thread/… 向下滚动到 Dwayne Need 的答案,他有一些异步加载演示的源代码,应该可以绕过您遇到的问题。
    • 好的,看起来我的问题更大,因为我在 BG 线程上创建了一个 BitmapImage 并试图将其传递给 UI 线程,但由于某种原因我无法克隆或冻结它,所以我最后只是将一个 byte[] 传递给 UI 线程并使用它构造一个图像......我会给你积分,因为你是唯一回答的人
    【解决方案3】:

    今天这仍然是一个问题!按照 Bohdan 的建议将数据包装在 WriteableBitmap 中是可行的,但该类型有一个前后缓冲区,它的内存占用量增加了一倍。 CachedBitmap 是更好的选择。

    new CachedBitmap(bitmapSource, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
    

    除非您喜欢惊喜,否则请使用BitmapCacheOption.OnLoad,并记得冻结生成的对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 2013-01-16
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多