Use Customized LazyAsync class to load image instead of the weird way of updating lazy class async

This commit is contained in:
弘韬 张 2020-11-16 12:46:39 +08:00
parent e7c02dac72
commit 0a9bad3ffa
2 changed files with 51 additions and 17 deletions

View file

@ -18,6 +18,8 @@ namespace Flow.Launcher.Infrastructure.Image
private static readonly ConcurrentDictionary<string, string> GuidToKey = new ConcurrentDictionary<string, string>(); private static readonly ConcurrentDictionary<string, string> GuidToKey = new ConcurrentDictionary<string, string>();
private static IImageHashGenerator _hashGenerator; private static IImageHashGenerator _hashGenerator;
private static bool EnableImageHash = true; private static bool EnableImageHash = true;
public static ImageSource defaultImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon));
private static readonly string[] ImageExtensions = private static readonly string[] ImageExtensions =
{ {
@ -37,6 +39,7 @@ namespace Flow.Launcher.Infrastructure.Image
var usage = LoadStorageToConcurrentDictionary(); var usage = LoadStorageToConcurrentDictionary();
foreach (var icon in new[] { Constant.DefaultIcon, Constant.MissingImgIcon }) foreach (var icon in new[] { Constant.DefaultIcon, Constant.MissingImgIcon })
{ {
ImageSource img = new BitmapImage(new Uri(icon)); ImageSource img = new BitmapImage(new Uri(icon));
@ -213,13 +216,10 @@ namespace Flow.Launcher.Infrastructure.Image
public static bool CacheContainImage(string path) public static bool CacheContainImage(string path)
{ {
return ImageCache.ContainsKey(path); return ImageCache.ContainsKey(path) && ImageCache[path] != null;
}
public static ImageSource LoadDefault(bool loadFullImage = false)
{
return LoadInternal(Constant.MissingImgIcon, loadFullImage).ImageSource;
} }
public static ImageSource Load(string path, bool loadFullImage = false) public static ImageSource Load(string path, bool loadFullImage = false)
{ {
var imageResult = LoadInternal(path, loadFullImage); var imageResult = LoadInternal(path, loadFullImage);

View file

@ -8,18 +8,57 @@ using Flow.Launcher.Infrastructure.Image;
using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin; using Flow.Launcher.Plugin;
using Microsoft.FSharp.Core;
namespace Flow.Launcher.ViewModel namespace Flow.Launcher.ViewModel
{ {
public class ResultViewModel : BaseModel public class ResultViewModel : BaseModel
{ {
public class LazyAsync<T> : Lazy<Task<T>>
{
private T defaultValue;
private readonly Action _updateCallback;
public T Value
{
get
{
if (!IsValueCreated)
{
base.Value.ContinueWith(_ =>
{
_updateCallback();
});
return defaultValue;
}
else if (!base.Value.IsCompleted)
{
return defaultValue;
}
else return base.Value.Result;
}
}
public LazyAsync(Func<Task<T>> factory, T defaultValue, Action updateCallback) : base(factory)
{
if (defaultValue != null)
{
this.defaultValue = defaultValue;
}
_updateCallback = updateCallback;
}
}
public ResultViewModel(Result result, Settings settings) public ResultViewModel(Result result, Settings settings)
{ {
if (result != null) if (result != null)
{ {
Result = result; Result = result;
Image = new Lazy<ImageSource>(SetImage); Image = new LazyAsync<ImageSource>(SetImage, ImageLoader.defaultImage, () =>
{
OnPropertyChanged(nameof(Image));
});
} }
Settings = settings; Settings = settings;
@ -39,9 +78,9 @@ namespace Flow.Launcher.ViewModel
? Result.SubTitle ? Result.SubTitle
: Result.SubTitleToolTip; : Result.SubTitleToolTip;
public Lazy<ImageSource> Image { get; set; } public LazyAsync<ImageSource> Image { get; set; }
private ImageSource SetImage() private async Task<ImageSource> SetImage()
{ {
var imagePath = Result.IcoPath; var imagePath = Result.IcoPath;
if (string.IsNullOrEmpty(imagePath) && Result.Icon != null) if (string.IsNullOrEmpty(imagePath) && Result.Icon != null)
@ -62,14 +101,9 @@ namespace Flow.Launcher.ViewModel
return ImageLoader.Load(imagePath); return ImageLoader.Load(imagePath);
else else
{ {
Task.Run(() => return await Task.Run(() => ImageLoader.Load(imagePath));
{
Image = new Lazy<ImageSource>(() => ImageLoader.Load(imagePath));
OnPropertyChanged(nameof(Image));
});
return ImageLoader.LoadDefault();
} }
} }
public Result Result { get; } public Result Result { get; }