Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions Flow.Launcher/ViewModel/ResultViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
Expand All @@ -12,9 +13,9 @@ namespace Flow.Launcher.ViewModel
{
public class ResultViewModel : BaseModel
{
public class LazyAsync<T> : Lazy<Task<T>>
public class LazyAsync<T> : Lazy<ValueTask<T>>
{
private T defaultValue;
private readonly T defaultValue;

private readonly Action _updateCallback;
public new T Value
Expand All @@ -23,21 +24,27 @@ public class LazyAsync<T> : Lazy<Task<T>>
{
if (!IsValueCreated)
{
base.Value.ContinueWith(_ =>
{
_updateCallback();
});
_ = Exercute(); // manually use callback strategy

return defaultValue;
}
if (!base.Value.IsCompleted || base.Value.IsFaulted)

if (!base.Value.IsCompletedSuccessfully)
return defaultValue;

return base.Value.Result;

// If none of the variables captured by the local function are captured by other lambdas,
// the compiler can avoid heap allocations.
async ValueTask Exercute()
{
await base.Value.ConfigureAwait(false);
_updateCallback();
}

}
}
public LazyAsync(Func<Task<T>> factory, T defaultValue, Action updateCallback) : base(factory)
public LazyAsync(Func<ValueTask<T>> factory, T defaultValue, Action updateCallback) : base(factory)
{
if (defaultValue != null)
{
Expand All @@ -55,13 +62,13 @@ public ResultViewModel(Result result, Settings settings)
Result = result;

Image = new LazyAsync<ImageSource>(
SetImage,
SetImage,
ImageLoader.DefaultImage,
() =>
{
OnPropertyChanged(nameof(Image));
});
}
}

Settings = settings;
}
Expand All @@ -82,7 +89,7 @@ public ResultViewModel(Result result, Settings settings)

public LazyAsync<ImageSource> Image { get; set; }

private async Task<ImageSource> SetImage()
private async ValueTask<ImageSource> SetImage()
{
var imagePath = Result.IcoPath;
if (string.IsNullOrEmpty(imagePath) && Result.Icon != null)
Expand All @@ -94,7 +101,7 @@ private async Task<ImageSource> SetImage()
catch (Exception e)
{
Log.Exception($"|ResultViewModel.Image|IcoPath is empty and exception when calling Icon() for result <{Result.Title}> of plugin <{Result.PluginDirectory}>", e);
imagePath = Constant.MissingImgIcon;
return ImageLoader.DefaultImage;
}
}

Expand Down