Using CancellationToken
This commit is contained in:
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using FileTime.App.Core.Tab;
|
||||
using System.Threading.Tasks;
|
||||
using FileTime.Core.Models;
|
||||
using System.Threading;
|
||||
|
||||
namespace FileTime.Avalonia.Application
|
||||
{
|
||||
@@ -71,12 +72,13 @@ namespace FileTime.Avalonia.Application
|
||||
}
|
||||
}
|
||||
|
||||
private async Task TabItemMarked(TabState tabState, AbsolutePath item)
|
||||
private async Task TabItemMarked(TabState tabState, AbsolutePath item, CancellationToken token = default)
|
||||
{
|
||||
var tabContainer = Tabs.FirstOrDefault(t => t.TabState == tabState);
|
||||
if (tabContainer != null)
|
||||
{
|
||||
var item2 = (await tabContainer.CurrentLocation.GetItems()).FirstOrDefault(i => i.Item.FullName == item.Path);
|
||||
var item2 = (await tabContainer.CurrentLocation.GetItems(token)).FirstOrDefault(i => i.Item.FullName == item.Path);
|
||||
if (token.IsCancellationRequested) return;
|
||||
if (item2 != null)
|
||||
{
|
||||
item2.IsMarked = true;
|
||||
@@ -84,12 +86,13 @@ namespace FileTime.Avalonia.Application
|
||||
}
|
||||
}
|
||||
|
||||
private async Task TabItemUnmarked(TabState tabState, AbsolutePath item)
|
||||
private async Task TabItemUnmarked(TabState tabState, AbsolutePath item, CancellationToken token = default)
|
||||
{
|
||||
var tabContainer = Tabs.FirstOrDefault(t => t.TabState == tabState);
|
||||
if (tabContainer != null)
|
||||
{
|
||||
var item2 = (await tabContainer.CurrentLocation.GetItems()).FirstOrDefault(i => i.Item.FullName == item.Path);
|
||||
var item2 = (await tabContainer.CurrentLocation.GetItems(token)).FirstOrDefault(i => i.Item.FullName == item.Path);
|
||||
if (token.IsCancellationRequested) return;
|
||||
if (item2 != null)
|
||||
{
|
||||
item2.IsMarked = false;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FileTime.Avalonia.ViewModels;
|
||||
|
||||
@@ -5,6 +6,6 @@ namespace FileTime.Avalonia.Application
|
||||
{
|
||||
public interface INewItemProcessor
|
||||
{
|
||||
Task UpdateMarkedItems(ContainerViewModel containerViewModel);
|
||||
Task UpdateMarkedItems(ContainerViewModel containerViewModel, CancellationToken token = default);
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using FileTime.App.Core.Tab;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace FileTime.Avalonia.Application
|
||||
{
|
||||
@@ -40,21 +40,30 @@ namespace FileTime.Avalonia.Application
|
||||
|
||||
private IItemViewModel? _selectedItem;
|
||||
|
||||
[Obsolete($"Use {nameof(SetSelectedItemAsync)} instead.")]
|
||||
public IItemViewModel? SelectedItem
|
||||
{
|
||||
get => _selectedItem;
|
||||
set
|
||||
{
|
||||
if (_selectedItem != value)// && value != null
|
||||
if (value != null)
|
||||
{
|
||||
_selectedItem = value;
|
||||
|
||||
OnPropertyChanged("SelectedItem");
|
||||
SelectedItemChanged().Wait();
|
||||
SetSelectedItemAsync(value, true).Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetSelectedItemAsync(IItemViewModel? value, bool fromDataBinding = false)
|
||||
{
|
||||
if (_selectedItem != value)
|
||||
{
|
||||
_selectedItem = value;
|
||||
|
||||
OnPropertyChanged(nameof(SelectedItem));
|
||||
await Tab.SetCurrentSelectedItem(SelectedItem?.Item, fromDataBinding);
|
||||
}
|
||||
}
|
||||
|
||||
partial void OnInitialize()
|
||||
{
|
||||
_tabState = new TabState(Tab);
|
||||
@@ -96,18 +105,20 @@ namespace FileTime.Avalonia.Application
|
||||
return parent;
|
||||
}
|
||||
|
||||
private async Task Tab_CurrentLocationChanged(object? sender, AsyncEventArgs e)
|
||||
private async Task Tab_CurrentLocationChanged(object? sender, AsyncEventArgs e, CancellationToken token = default)
|
||||
{
|
||||
var currentLocation = await Tab.GetCurrentLocation();
|
||||
var currentLocation = await Tab.GetCurrentLocation(token);
|
||||
var parent = GenerateParent(currentLocation);
|
||||
CurrentLocation = new ContainerViewModel(this, parent, currentLocation, ItemNameConverterService);
|
||||
await CurrentLocation.Init();
|
||||
await CurrentLocation.Init(token: token);
|
||||
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
parent.ChildrenToAdopt.Add(CurrentLocation);
|
||||
Parent = parent;
|
||||
await Parent.Init();
|
||||
await Parent.Init(token: token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -115,42 +126,47 @@ namespace FileTime.Avalonia.Application
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Tab_CurrentSelectedItemChanged(object? sender, AsyncEventArgs e)
|
||||
private async Task Tab_CurrentSelectedItemChanged(object? sender, AsyncEventArgs e, CancellationToken token = default)
|
||||
{
|
||||
await UpdateCurrentSelectedItem();
|
||||
await UpdateCurrentSelectedItem(token);
|
||||
}
|
||||
|
||||
public async Task UpdateCurrentSelectedItem()
|
||||
public async Task UpdateCurrentSelectedItem(CancellationToken token = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tabCurrentSelectenItem = await Tab.GetCurrentSelectedItem();
|
||||
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
IItemViewModel? currentSelectenItem = null;
|
||||
if (tabCurrentSelectenItem == null)
|
||||
{
|
||||
SelectedItem = null;
|
||||
await SetSelectedItemAsync(null);
|
||||
ChildContainer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSelectenItem = (await _currentLocation.GetItems()).FirstOrDefault(i => i.Item.Name == tabCurrentSelectenItem.Name);
|
||||
currentSelectenItem = (await _currentLocation.GetItems(token)).FirstOrDefault(i => i.Item.Name == tabCurrentSelectenItem.Name);
|
||||
if (currentSelectenItem is ContainerViewModel currentSelectedContainer)
|
||||
{
|
||||
SelectedItem = currentSelectedContainer;
|
||||
await SetSelectedItemAsync(currentSelectedContainer);
|
||||
ChildContainer = currentSelectedContainer;
|
||||
}
|
||||
else if (currentSelectenItem is ElementViewModel element)
|
||||
{
|
||||
SelectedItem = element;
|
||||
await SetSelectedItemAsync(element);
|
||||
ChildContainer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedItem = null;
|
||||
await SetSelectedItemAsync(null);
|
||||
ChildContainer = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
var items = await _currentLocation.GetItems();
|
||||
if (items?.Count > 0)
|
||||
{
|
||||
@@ -173,6 +189,7 @@ namespace FileTime.Avalonia.Application
|
||||
var child = item;
|
||||
while (child is ContainerViewModel containerViewModel && containerViewModel.Container.IsLoaded)
|
||||
{
|
||||
if (token.IsCancellationRequested) return;
|
||||
var activeChildItem = await Tab.GetItemByLastPath(containerViewModel.Container);
|
||||
child = (await containerViewModel.GetItems()).FirstOrDefault(i => i.Item == activeChildItem);
|
||||
if (child != null)
|
||||
@@ -199,22 +216,13 @@ namespace FileTime.Avalonia.Application
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
catch
|
||||
{
|
||||
//INFO collection modified exception on: currentSelectenItem = (await _currentLocation.GetItems()).FirstOrDefault(i => i.Item.Name == tabCurrentSelectenItem.Name);
|
||||
//TODO: handle or error message
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SelectedItemChanged()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Tab.SetCurrentSelectedItem(SelectedItem?.Item);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public async Task SetCurrentSelectedItem(IItem newItem)
|
||||
{
|
||||
try
|
||||
@@ -309,13 +317,14 @@ namespace FileTime.Avalonia.Application
|
||||
await _tabState.MakrCurrentItem();
|
||||
}
|
||||
|
||||
public async Task UpdateMarkedItems(ContainerViewModel containerViewModel)
|
||||
public async Task UpdateMarkedItems(ContainerViewModel containerViewModel, CancellationToken token = default)
|
||||
{
|
||||
if (containerViewModel == CurrentLocation && containerViewModel.Container.IsLoaded)
|
||||
{
|
||||
if (token.IsCancellationRequested) return;
|
||||
var selectedItems = TabState.GetCurrentMarkedItems(containerViewModel.Container);
|
||||
|
||||
foreach (var item in await containerViewModel.GetItems())
|
||||
foreach (var item in await containerViewModel.GetItems(token))
|
||||
{
|
||||
item.IsMarked = selectedItems.Any(c => c.Path == item.Item.FullName);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FileTime.Avalonia.Application;
|
||||
using System.Threading;
|
||||
|
||||
namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
@@ -130,21 +131,22 @@ namespace FileTime.Avalonia.ViewModels
|
||||
|
||||
public void InvalidateDisplayName() => OnPropertyChanged(nameof(DisplayName));
|
||||
|
||||
public async Task Init(bool initializeChildren = true)
|
||||
public async Task Init(bool initializeChildren = true, CancellationToken token = default)
|
||||
{
|
||||
await Refresh(initializeChildren);
|
||||
await Refresh(initializeChildren, token);
|
||||
}
|
||||
|
||||
private async Task Container_Refreshed(object? sender, AsyncEventArgs e)
|
||||
private async Task Container_Refreshed(object? sender, AsyncEventArgs e, CancellationToken token = default)
|
||||
{
|
||||
await Refresh(false);
|
||||
await Refresh(false, token);
|
||||
}
|
||||
|
||||
[Obsolete($"Use the parametrizable version of {nameof(Refresh)}.")]
|
||||
private async Task Refresh()
|
||||
{
|
||||
await Refresh(true);
|
||||
}
|
||||
private async Task Refresh(bool initializeChildren)
|
||||
private async Task Refresh(bool initializeChildren, CancellationToken token = default)
|
||||
{
|
||||
if (_isRefreshing) return;
|
||||
|
||||
@@ -157,6 +159,9 @@ namespace FileTime.Avalonia.ViewModels
|
||||
|
||||
var containers = (await _container.GetContainers())!.Select(c => AdoptOrReuseOrCreateItem(c, (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))).ToList();
|
||||
var elements = (await _container.GetElements())!.Select(e => AdoptOrReuseOrCreateItem(e, (e2) => new ElementViewModel(e2, this, ItemNameConverterService))).ToList();
|
||||
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
Exceptions = new List<Exception>(_container.Exceptions);
|
||||
|
||||
foreach (var containerToRemove in _containers.Except(containers))
|
||||
@@ -168,7 +173,8 @@ namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
foreach (var container in containers)
|
||||
{
|
||||
await container.Init(false);
|
||||
if (token.IsCancellationRequested) return;
|
||||
await container.Init(false, token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,21 +226,21 @@ namespace FileTime.Avalonia.ViewModels
|
||||
_items = new ObservableCollection<IItemViewModel>();
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<ContainerViewModel>> GetContainers()
|
||||
public async Task<ObservableCollection<ContainerViewModel>> GetContainers(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(Refresh);
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token), token);
|
||||
return _containers;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<ElementViewModel>> GetElements()
|
||||
public async Task<ObservableCollection<ElementViewModel>> GetElements(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(Refresh);
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token), token);
|
||||
return _elements;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<IItemViewModel>> GetItems()
|
||||
public async Task<ObservableCollection<IItemViewModel>> GetItems(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(Refresh);
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token), token);
|
||||
return _items;
|
||||
}
|
||||
|
||||
|
||||
@@ -605,7 +605,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
|
||||
private async Task RefreshCurrentLocation()
|
||||
{
|
||||
await AppState.SelectedTab.CurrentLocation.Container.Refresh();
|
||||
await AppState.SelectedTab.CurrentLocation.Container.RefreshAsync();
|
||||
await AppState.SelectedTab.UpdateCurrentSelectedItem();
|
||||
}
|
||||
|
||||
@@ -640,7 +640,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
var possibleContainer = await contentProvider.GetByPath(path);
|
||||
if (possibleContainer is IContainer container)
|
||||
{
|
||||
AppState.SelectedTab.OpenContainer(container).Wait();
|
||||
await AppState.SelectedTab.OpenContainer(container);
|
||||
}
|
||||
//TODO: multiple possible content provider handler
|
||||
return;
|
||||
@@ -873,7 +873,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
|
||||
var selectedItemName = AppState.SelectedTab.SelectedItem?.Item.Name;
|
||||
var currentLocationItems = await AppState.SelectedTab.CurrentLocation.GetItems();
|
||||
if (currentLocationItems.FirstOrDefault(i => i.Item.Name.ToLower() == AppState.RapidTravelText.ToLower()) is IItemViewModel matchItem)
|
||||
if (currentLocationItems.FirstOrDefault(i => string.Equals(i.Item.Name, AppState.RapidTravelText, StringComparison.OrdinalIgnoreCase)) is IItemViewModel matchItem)
|
||||
{
|
||||
await AppState.SelectedTab.SetCurrentSelectedItem(matchItem.Item);
|
||||
}
|
||||
@@ -882,7 +882,6 @@ namespace FileTime.Avalonia.ViewModels
|
||||
await AppState.SelectedTab.MoveCursorToFirst();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -899,7 +898,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
}
|
||||
private void ReadInputs(List<Core.Interactions.InputElement> inputs, Func<Task> inputHandler)
|
||||
{
|
||||
Inputs = inputs.Select(i => new InputElementWrapper(i, i.DefaultValue)).ToList();
|
||||
Inputs = inputs.ConvertAll(i => new InputElementWrapper(i, i.DefaultValue));
|
||||
_inputHandler = inputHandler;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsyncEvent;
|
||||
using FileTime.Core.Command;
|
||||
@@ -27,7 +28,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
_commandTimeState.Command.ProgressChanged.Add(HandleProgressChange);
|
||||
}
|
||||
|
||||
private Task HandleProgressChange(object? sender, AsyncEventArgs e)
|
||||
private Task HandleProgressChange(object? sender, AsyncEventArgs e, CancellationToken token = default)
|
||||
{
|
||||
Progress = _commandTimeState.Command.Progress;
|
||||
return Task.CompletedTask;
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace FileTime.Avalonia.Views
|
||||
&& sender is StyledElement control
|
||||
&& control.DataContext is PlaceInfo placeInfo)
|
||||
{
|
||||
ViewModel.OpenContainer(placeInfo.Container).Wait();
|
||||
ViewModel.OpenContainer(placeInfo.Container);
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user