Merge pull request #343 from taooceros/ReplaceTPL

Use Channel instead of BufferBlock
This commit is contained in:
Jeremy Wu 2021-02-16 07:31:29 +11:00 committed by GitHub
commit 35d3f42ef4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 24 deletions

View file

@ -19,6 +19,7 @@ using Flow.Launcher.Plugin;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Storage;
using Flow.Launcher.Infrastructure.Logger;
using System.Threading.Channels;
namespace Flow.Launcher.ViewModel
{
@ -46,7 +47,7 @@ namespace Flow.Launcher.ViewModel
private readonly Internationalization _translator = InternationalizationManager.Instance;
private BufferBlock<ResultsForUpdate> _resultsUpdateQueue;
private ChannelWriter<ResultsForUpdate> _resultsUpdateChannelWriter;
private Task _resultsViewUpdateTask;
#endregion
@ -85,25 +86,31 @@ namespace Flow.Launcher.ViewModel
private void RegisterViewUpdate()
{
_resultsUpdateQueue = new BufferBlock<ResultsForUpdate>();
var resultUpdateChannel = Channel.CreateUnbounded<ResultsForUpdate>();
_resultsUpdateChannelWriter = resultUpdateChannel.Writer;
_resultsViewUpdateTask =
Task.Run(updateAction).ContinueWith(continueAction, TaskContinuationOptions.OnlyOnFaulted);
async Task updateAction()
{
var queue = new Dictionary<string, ResultsForUpdate>();
while (await _resultsUpdateQueue.OutputAvailableAsync())
var channelReader = resultUpdateChannel.Reader;
// it is not supposed to be false because it won't be complete
while (await channelReader.WaitToReadAsync())
{
queue.Clear();
await Task.Delay(20);
while (_resultsUpdateQueue.TryReceive(out var item))
while (channelReader.TryRead(out var item))
{
if (!item.Token.IsCancellationRequested)
queue[item.ID] = item;
}
UpdateResultView(queue.Values);
queue.Clear();
}
Log.Error("MainViewModel", "Unexpected ResultViewUpdate ends");
};
void continueAction(Task t)
@ -128,7 +135,10 @@ namespace Flow.Launcher.ViewModel
if (e.Query.RawQuery == QueryText) // TODO: allow cancellation
{
PluginManager.UpdatePluginMetadata(e.Results, pair.Metadata, e.Query);
_resultsUpdateQueue.Post(new ResultsForUpdate(e.Results, pair.Metadata, e.Query, _updateToken));
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(e.Results, pair.Metadata, e.Query, _updateToken)))
{
Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
};
}
};
}
@ -529,9 +539,12 @@ namespace Flow.Launcher.ViewModel
await Task.Yield();
var results = await PluginManager.QueryForPlugin(plugin, query, currentCancellationToken);
if (!currentCancellationToken.IsCancellationRequested && results != null)
_resultsUpdateQueue.Post(new ResultsForUpdate(results, plugin.Metadata, query,
currentCancellationToken));
if (currentCancellationToken.IsCancellationRequested || results == null) return;
if (!_resultsUpdateChannelWriter.TryWrite(new ResultsForUpdate(results, plugin.Metadata, query, currentCancellationToken)))
{
Log.Error("MainViewModel", "Unable to add item to Result Update Queue");
};
}
}, currentCancellationToken)
.ContinueWith(t => Log.Exception("|MainViewModel|Plugins Query Exceptions", t.Exception),

View file

@ -6,7 +6,7 @@ using System.Threading;
namespace Flow.Launcher.ViewModel
{
public class ResultsForUpdate
public struct ResultsForUpdate
{
public List<Result> Results { get; }
@ -16,13 +16,6 @@ namespace Flow.Launcher.ViewModel
public Query Query { get; }
public CancellationToken Token { get; }
public ResultsForUpdate(List<Result> results, string resultID, CancellationToken token)
{
Results = results;
ID = resultID;
Token = token;
}
public ResultsForUpdate(List<Result> results, PluginMetadata metadata, Query query, CancellationToken token)
{
Results = results;

View file

@ -183,13 +183,12 @@ namespace Flow.Launcher.ViewModel
private List<ResultViewModel> NewResults(List<Result> newRawResults, string resultId)
{
if (newRawResults.Count == 0)
return Results.ToList();
return Results;
var results = Results as IEnumerable<ResultViewModel>;
var newResults = newRawResults.Select(r => new ResultViewModel(r, _settings));
return results.Where(r => r.Result.PluginID != resultId)
return Results.Where(r => r.Result.PluginID != resultId)
.Concat(newResults)
.OrderByDescending(r => r.Result.Score)
.ToList();
@ -198,11 +197,9 @@ namespace Flow.Launcher.ViewModel
private List<ResultViewModel> NewResults(IEnumerable<ResultsForUpdate> resultsForUpdates)
{
if (!resultsForUpdates.Any())
return Results.ToList();
return Results;
var results = Results as IEnumerable<ResultViewModel>;
return results.Where(r => r != null && !resultsForUpdates.Any(u => u.Metadata.ID == r.Result.PluginID))
return Results.Where(r => r != null && !resultsForUpdates.Any(u => u.ID == r.Result.PluginID))
.Concat(resultsForUpdates.SelectMany(u => u.Results, (u, r) => new ResultViewModel(r, _settings)))
.OrderByDescending(rv => rv.Result.Score)
.ToList();