Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步加载时WPF表单上不显示的图像_C#_Wpf_Multithreading_Listbox_Backgroundworker - Fatal编程技术网

C# 异步加载时WPF表单上不显示的图像

C# 异步加载时WPF表单上不显示的图像,c#,wpf,multithreading,listbox,backgroundworker,C#,Wpf,Multithreading,Listbox,Backgroundworker,我正在尝试显示(在带有自定义数据模板的列表框中)从多页tiff图像中提取的一系列位图源帧(缩略图)。当我在UI线程上处理tiff时,或者直接将图像添加到listbox的项集合,或者将它们添加到绑定的ObservableCollection,它们在列表中显示良好。但是,当尝试异步加载每个缩略图时(使用BackgroundWorker或使用异步任务),我会看到无法解决的行为: 第一个缩略图按预期加载 下一个和所有后续缩略图都会获取列表中的项目(我看到边框),但显示的只是一个空白图像。它显示正确的项

我正在尝试显示(在带有自定义数据模板的列表框中)从多页tiff图像中提取的一系列位图源帧(缩略图)。当我在UI线程上处理tiff时,或者直接将图像添加到listbox的项集合,或者将它们添加到绑定的ObservableCollection,它们在列表中显示良好。但是,当尝试异步加载每个缩略图时(使用BackgroundWorker或使用异步任务),我会看到无法解决的行为:

  • 第一个缩略图按预期加载
  • 下一个和所有后续缩略图都会获取列表中的项目(我看到边框),但显示的只是一个空白图像。它显示正确的项目数,但第一个项目后没有图像
我一直在尝试冻结缩略图(不好),尝试将它们发送回UI线程,并通过worker的ReportProgress将它们添加到集合中(不好),但我似乎无法让它们显示出来

处理UI线程(其中SyncImages是绑定到我的列表框的ObservableCollection,OnPropertyChanged处理通知事件):

不起作用(本例将帧直接添加到列表中,但我也尝试通过绑定,结果没有任何差异):

希望有人能对这里发生的事情有所了解。我知道代码用于提取帧,因此即使在异步示例中,也必须加载帧,但UI线程似乎无法访问保存图像数据的源属性以在表单上显示它们(这就是我尝试冻结的原因)

任何想法都将不胜感激


示例图片:

@Clemens对原始问题的评论给出了答案。确保文件流以负责任的方式关闭,并将
BitmapCacheOption
更改为
OnLoad
现在显示异步加载中的每个图像

异步加载的最终代码如下所示:

private void LoadAsync(object sender, DoWorkEventArgs e)
    {
        BitmapDecoder decoder;

        using (Stream imageStreamSource = new FileStream(ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat,
                BitmapCacheOption.OnLoad);

        }

        foreach (var frame in decoder.Frames)
        {
            frame.Freeze();
            (sender as BackgroundWorker).ReportProgress(0, frame);
        }
    }

    private void UpdateAsync(object send, ProgressChangedEventArgs e)
    {
            SyncImages.Add((BitmapSource)e.UserState);
            OnPropertyChanged("SyncImages");

    }

不知道为什么冻结不起作用,你可以在这里看一些其他的建议:谢谢你的链接-我一直在看这些建议,看看是否有什么解决办法。我附上了一张图片,希望它能引发一个建议:左边是UI线程处理结果,右边是BackgroundWorker/async版本。您是否在任何地方关闭文件流?为了确保立即加载所有帧,并且在创建BitmapFrames后可以立即关闭流,您应该设置
BitmapCacheOption.OnLoad
而不是
Default
@Clemens,您关于
BitmapCacheOption.OnLoad
的建议成功了!谢谢你的帮助!
private void LoadAsync(object sender, DoWorkEventArgs e)
{
    Stream imageStreamSource = new FileStream(ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
    var decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat,
        BitmapCacheOption.Default);

    foreach (var frame in decoder.Frames)
    {
        // frame.Freeze();
        (sender as BackgroundWorker).ReportProgress(0, frame);
    }

    OnPropertyChanged("AsyncImages");
}

private void ReportAsyncProgress(object send, ProgressChangedEventArgs e)
    {
        var frame = (BitmapSource) e.UserState;
        LbAsynchronous.Items.Add(frame);
    }
private void LoadAsync(object sender, DoWorkEventArgs e)
    {
        BitmapDecoder decoder;

        using (Stream imageStreamSource = new FileStream(ImagePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat,
                BitmapCacheOption.OnLoad);

        }

        foreach (var frame in decoder.Frames)
        {
            frame.Freeze();
            (sender as BackgroundWorker).ReportProgress(0, frame);
        }
    }

    private void UpdateAsync(object send, ProgressChangedEventArgs e)
    {
            SyncImages.Add((BitmapSource)e.UserState);
            OnPropertyChanged("SyncImages");

    }