这是问题所在。
我有一个视图,应该显示一个图像和一些控件。
用户添加新图像,更改某些选项,然后单击“完成”。
图像很大而且非常大(400-1500 MB Tiff)
用户应该看到图像的预览,但是如果加载10到15秒甚至更长的时间是可以的,那么他这次有工作。
图像通过MVVM
模式进行绑定,就像简单的字符串一样(文件始终位于本地文件夹中)
<Image Name="ImagePreview" Source="{Binding SFilePathForPreview,
FallbackValue={StaticResource DefaultImage},
TargetNullValue={StaticResource DefaultImage}}"
HorizontalAlignment="Center" Width="200" Height="200"
VerticalAlignment="Center" />
问题是,当用户尝试添加文件以进行加载时,所有内容都将挂起。 我知道这种情况应该通过多线程解决-但不知道如何实现。
我试图像这样从不同线程的视图中更新图像:
Thread newThread = new Thread(LazyLoad);
newThread.Name = "LazyLoad";
newThread.Start(SFilePathForPreview);
public void LazyLoad(object SFilePath)
{
try
{
string path = (string)SFilePath;
BitmapImage t_source = new BitmapImage();
t_source.BeginInit();
t_source.UriSource = new Uri(path);
t_source.DecodePixelWidth = 200;
t_source.EndInit();
t_source.Freeze();
this.Dispatcher.Invoke(new Action(delegate
{
ImagePreview.Source = t_source;
}));
}
catch
{
//...
}
}
但是无论如何
ImagePreview.Source = t_source;
一切都将挂起,直到图像完全加载。
是否可以在后台加载预览并显示这些预览而不会造成可怕的挂起?
答案 0 :(得分:0)
如前所述,您正在通过图像加载来阻止UI线程。您可以使用WriteableBitmap类实例作为Image的源。这将使您将图像加载到后台线程或异步任务上。这是有关此问题的快速指南(不是我的)。
https://www.i-programmer.info/programming/wpf-workings/527-writeablebitmap.html
答案 1 :(得分:0)
异步加载图像的最简单的方法可能是通过异步绑定。您完全不必处理线程或任务。
<Image Source="{Binding Image, IsAsync=True}"/>
可能的视图模型如下图所示,必须确保可以从后台线程调用Image
属性获取器。
public class ViewModel : ViewModelBase
{
private string imagePath;
private BitmapImage image;
public string ImagePath
{
get { return imagePath; }
set
{
imagePath = value;
image = null;
OnPropertyChanged(nameof(ImagePath));
OnPropertyChanged(nameof(Image));
}
}
public BitmapImage Image
{
get
{
lock (this)
{
if (image == null &&
!string.IsNullOrEmpty(imagePath) &&
File.Exists(imagePath))
{
using (var stream = File.OpenRead(imagePath))
{
image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.DecodePixelWidth = 200;
image.StreamSource = stream;
image.EndInit();
image.Freeze();
}
}
}
return image;
}
}
}
答案 2 :(得分:-1)
另一种选择是使用优先级绑定,其优先级最高的是完整图像,而优先级较低的是加载速度更快的预览图像。 MS已在此处记录了优先级绑定:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-prioritybinding