Gui startup optimizations
This commit is contained in:
@@ -70,7 +70,8 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
|
|
||||||
foreach (var (requestedTabNumber, nativePath) in _tabsToOpen.TabsToOpen)
|
foreach (var (requestedTabNumber, nativePath) in _tabsToOpen.TabsToOpen)
|
||||||
{
|
{
|
||||||
if (await _timelessContentProvider.GetItemByNativePathAsync(nativePath) is not IContainer container) continue;
|
if (await _timelessContentProvider.GetItemByNativePathAsync(nativePath) is not IContainer container)
|
||||||
|
continue;
|
||||||
|
|
||||||
containers.Add((requestedTabNumber, container));
|
containers.Add((requestedTabNumber, container));
|
||||||
}
|
}
|
||||||
@@ -111,14 +112,16 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<ITabViewModel>> LoadStatesAsync(bool createEmptyIfNecessary, CancellationToken token = default)
|
private async Task<IEnumerable<ITabViewModel>> LoadStatesAsync(
|
||||||
|
bool createEmptyIfNecessary,
|
||||||
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (!File.Exists(_settingsPath) || !_tabPersistenceSettings.LoadState)
|
if (!File.Exists(_settingsPath) || !_tabPersistenceSettings.LoadState)
|
||||||
{
|
{
|
||||||
if (createEmptyIfNecessary)
|
if (createEmptyIfNecessary)
|
||||||
{
|
{
|
||||||
var tabViewModel = await CreateEmptyTab();
|
var tabViewModel = await CreateEmptyTab();
|
||||||
return new[] {tabViewModel};
|
return new[] { tabViewModel };
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enumerable.Empty<ITabViewModel>();
|
return Enumerable.Empty<ITabViewModel>();
|
||||||
@@ -142,7 +145,7 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
if (createEmptyIfNecessary)
|
if (createEmptyIfNecessary)
|
||||||
{
|
{
|
||||||
var tabViewModel = await CreateEmptyTab();
|
var tabViewModel = await CreateEmptyTab();
|
||||||
return new[] {tabViewModel};
|
return new[] { tabViewModel };
|
||||||
}
|
}
|
||||||
|
|
||||||
return Enumerable.Empty<ITabViewModel>();
|
return Enumerable.Empty<ITabViewModel>();
|
||||||
@@ -162,7 +165,8 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
var tab = await _serviceProvider.GetAsyncInitableResolver<IContainer>(currentDirectory ?? _localContentProvider)
|
var tab = await _serviceProvider
|
||||||
|
.GetAsyncInitableResolver<IContainer>(currentDirectory ?? _localContentProvider)
|
||||||
.GetRequiredServiceAsync<ITab>();
|
.GetRequiredServiceAsync<ITab>();
|
||||||
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
|
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
|
||||||
|
|
||||||
@@ -265,8 +269,7 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
foreach (var tab in _appState.Tabs)
|
foreach (var tab in _appState.Tabs)
|
||||||
{
|
{
|
||||||
var currentLocation = tab.CurrentLocation.Value;
|
var currentLocation = tab.CurrentLocation.Value;
|
||||||
if (currentLocation is null) continue;
|
if (currentLocation?.FullName?.Path is not { } path) continue;
|
||||||
var path = currentLocation.FullName!.Path;
|
|
||||||
|
|
||||||
if (currentLocation.GetExtension<RealContainerProviderExtension>()?.RealContainer() is { } realPath)
|
if (currentLocation.GetExtension<RealContainerProviderExtension>()?.RealContainer() is { } realPath)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,7 +85,11 @@ public partial class MainWindowViewModel : IMainWindowViewModel
|
|||||||
_modalService.AllModalClosed += (_, _) => FocusDefaultElement?.Invoke();
|
_modalService.AllModalClosed += (_, _) => FocusDefaultElement?.Invoke();
|
||||||
_instanceMessageHandler.ShowWindow += () => ShowWindow?.Invoke();
|
_instanceMessageHandler.ShowWindow += () => ShowWindow?.Invoke();
|
||||||
|
|
||||||
Task.Run(async () => await _lifecycleService.InitStartupHandlersAsync()).Wait();
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await Task.Delay(100);
|
||||||
|
await _lifecycleService.InitStartupHandlersAsync();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessKeyDown(KeyEventArgs e)
|
public void ProcessKeyDown(KeyEventArgs e)
|
||||||
|
|||||||
@@ -51,39 +51,46 @@ public partial class MainWindow : Window, IUiAccessor
|
|||||||
_initializer = initializer;
|
_initializer = initializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnWindowOpened(object sender, EventArgs e)
|
private async void OnWindowOpened(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (DataContext is not MainWindowViewModel && !Design.IsDesignMode)
|
try
|
||||||
{
|
{
|
||||||
_initializer?.Invoke();
|
if (DataContext is not MainWindowViewModel && !Design.IsDesignMode)
|
||||||
|
|
||||||
_logger = DI.ServiceProvider.GetService<ILogger<MainWindow>>();
|
|
||||||
_modalService = DI.ServiceProvider.GetRequiredService<IModalService>();
|
|
||||||
DI.ServiceProvider.GetRequiredService<SystemClipboardService>().UiAccessor = this;
|
|
||||||
|
|
||||||
ReadInputContainer.PropertyChanged += ReadInputContainerOnPropertyChanged;
|
|
||||||
|
|
||||||
_logger?.LogInformation(
|
|
||||||
$"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization...");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var viewModel = DI.ServiceProvider.GetRequiredService<MainWindowViewModel>();
|
await Task.Delay(100);
|
||||||
viewModel.FocusDefaultElement = () => Focus();
|
_initializer?.Invoke();
|
||||||
viewModel.ShowWindow = Activate;
|
|
||||||
ViewModel = viewModel;
|
_logger = DI.ServiceProvider.GetService<ILogger<MainWindow>>();
|
||||||
}
|
_modalService = DI.ServiceProvider.GetRequiredService<IModalService>();
|
||||||
catch (Exception ex)
|
DI.ServiceProvider.GetRequiredService<SystemClipboardService>().UiAccessor = this;
|
||||||
{
|
|
||||||
_logger?.LogError(ex, "Error initializing {ViewModel}", nameof(MainWindowViewModel));
|
ReadInputContainer.PropertyChanged += ReadInputContainerOnPropertyChanged;
|
||||||
if (DataContext is IMainWindowViewModelBase mainWindowViewModelBase)
|
|
||||||
|
_logger?.LogInformation(
|
||||||
|
$"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization...");
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
mainWindowViewModelBase.FatalError.SetValueSafe(
|
var viewModel = DI.ServiceProvider.GetRequiredService<MainWindowViewModel>();
|
||||||
$"Error initializing {nameof(MainWindowViewModel)}: " + ex.Message
|
viewModel.FocusDefaultElement = () => Focus();
|
||||||
);
|
viewModel.ShowWindow = Activate;
|
||||||
|
ViewModel = viewModel;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger?.LogError(ex, "Error initializing {ViewModel}", nameof(MainWindowViewModel));
|
||||||
|
if (DataContext is IMainWindowViewModelBase mainWindowViewModelBase)
|
||||||
|
{
|
||||||
|
mainWindowViewModelBase.FatalError.SetValueSafe(
|
||||||
|
$"Error initializing {nameof(MainWindowViewModel)}: " + ex.Message
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnKeyDown(object sender, KeyEventArgs e)
|
private void OnKeyDown(object sender, KeyEventArgs e)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using FileTime.Server;
|
|||||||
using FileTime.Tools.Compression;
|
using FileTime.Tools.Compression;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace FileTime.GuiApp;
|
namespace FileTime.GuiApp;
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ public class Application : Avalonia.Application
|
|||||||
{
|
{
|
||||||
private static void InitializeApp()
|
private static void InitializeApp()
|
||||||
{
|
{
|
||||||
|
Log.Logger.Information("App initialization starting...");
|
||||||
var configuration = Startup.CreateConfiguration();
|
var configuration = Startup.CreateConfiguration();
|
||||||
var services = DependencyInjection
|
var services = DependencyInjection
|
||||||
.RegisterDefaultServices(configuration: configuration)
|
.RegisterDefaultServices(configuration: configuration)
|
||||||
@@ -62,6 +64,7 @@ public class Application : Avalonia.Application
|
|||||||
{
|
{
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
|
Log.Logger.Information("Creating MainWindow instance...");
|
||||||
desktop.MainWindow = new MainWindow(InitializeApp)
|
desktop.MainWindow = new MainWindow(InitializeApp)
|
||||||
{
|
{
|
||||||
DataContext = new MainWindowLoadingViewModel(),
|
DataContext = new MainWindowLoadingViewModel(),
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ public static class Program
|
|||||||
.WriteTo.File(
|
.WriteTo.File(
|
||||||
Path.Combine(logFolder, "appLog.log"),
|
Path.Combine(logFolder, "appLog.log"),
|
||||||
fileSizeLimitBytes: 10 * 1024 * 1024,
|
fileSizeLimitBytes: 10 * 1024 * 1024,
|
||||||
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}",
|
outputTemplate:
|
||||||
|
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}",
|
||||||
rollingInterval: RollingInterval.Day,
|
rollingInterval: RollingInterval.Day,
|
||||||
rollOnFileSizeLimit: true)
|
rollOnFileSizeLimit: true)
|
||||||
.CreateBootstrapLogger();
|
.CreateBootstrapLogger();
|
||||||
@@ -128,15 +129,16 @@ public static class Program
|
|||||||
{
|
{
|
||||||
Log.CloseAndFlush();
|
Log.CloseAndFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avalonia configuration, don't remove; also used by visual designer.
|
// Avalonia configuration, don't remove; also used by visual designer.
|
||||||
public static AppBuilder BuildAvaloniaApp()
|
public static AppBuilder BuildAvaloniaApp()
|
||||||
=> AppBuilder.Configure<Application>()
|
=> AppBuilder.Configure<Application>()
|
||||||
.UsePlatformDetect()
|
.UsePlatformDetect()
|
||||||
.UseReactiveUI()
|
#if DEBUG
|
||||||
.LogToTrace();
|
.LogToTrace()
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
private static void OnTaskSchedulerUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
|
private static void OnTaskSchedulerUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
|
||||||
=> HandleUnhandledException(sender, e.Exception);
|
=> HandleUnhandledException(sender, e.Exception);
|
||||||
|
|||||||
Reference in New Issue
Block a user