From 428af4ac1c8ed0ab1da514fe963ec29fa58b5690 Mon Sep 17 00:00:00 2001 From: hishitetsu <66369541+hishitetsu@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:22:48 +0900 Subject: [PATCH 1/2] EnqueueOrInvokeAsync --- src/Files.App/App.xaml.cs | 4 +- src/Files.App/BaseLayout.cs | 4 +- .../NavigationControlItems/DriveItem.cs | 2 +- .../NavigationControlItems/LocationItem.cs | 2 +- .../DataModels/SidebarPinnedModel.cs | 6 +- .../Extensions/DispatcherQueueExtensions.cs | 48 ++++++++++++++ .../Filesystem/Cloud/CloudDrivesManager.cs | 5 +- .../Filesystem/Search/FolderSearch.cs | 2 +- src/Files.App/Helpers/DynamicDialogFactory.cs | 2 +- src/Files.App/Helpers/MenuFlyoutHelper.cs | 3 +- src/Files.App/Helpers/ThemeHelper.cs | 2 +- .../BaseLayoutCommandImplementationModel.cs | 2 +- .../RemovableDrivesService.cs | 3 +- .../ThreadingService.cs | 5 +- .../UserControls/Widgets/DrivesWidget.xaml.cs | 4 +- .../Widgets/QuickAccessWidget.xaml.cs | 4 +- .../Widgets/RecentFilesWidget.xaml.cs | 2 +- src/Files.App/ViewModels/ItemViewModel.cs | 62 +++++++++---------- .../ViewModels/Previews/BasePreviewModel.cs | 5 +- .../Previews/ImagePreviewViewModel.cs | 3 +- .../Previews/PDFPreviewViewModel.cs | 3 +- .../ViewModels/Properties/BaseProperties.cs | 2 +- .../Properties/CustomizationViewModel.cs | 7 ++- .../ViewModels/Properties/FileProperties.cs | 2 +- .../ViewModels/Properties/FolderProperties.cs | 2 +- .../ViewModels/Properties/HashesViewModel.cs | 2 +- src/Files.App/ViewModels/SidebarViewModel.cs | 2 +- src/Files.App/ViewModels/ToolbarViewModel.cs | 2 +- src/Files.App/Views/BaseShellPage.cs | 2 +- .../Views/Properties/GeneralPage.xaml.cs | 11 ++-- .../Properties/MainPropertiesPage.xaml.cs | 4 +- .../Properties/SecurityAdvancedPage.xaml.cs | 4 +- .../Views/Properties/SecurityPage.xaml.cs | 2 +- .../Views/Properties/ShortcutPage.xaml.cs | 3 +- 34 files changed, 138 insertions(+), 80 deletions(-) create mode 100644 src/Files.App/Extensions/DispatcherQueueExtensions.cs diff --git a/src/Files.App/App.xaml.cs b/src/Files.App/App.xaml.cs index 4e94ff20c1d5..879ba6598606 100644 --- a/src/Files.App/App.xaml.cs +++ b/src/Files.App/App.xaml.cs @@ -270,7 +270,7 @@ public void OnActivated(AppActivationArguments activatedEventArgs) var data = activatedEventArgs.Data; // InitializeApplication accesses UI, needs to be called on UI thread - _ = Window.DispatcherQueue.EnqueueAsync(() => Window.InitializeApplication(data)); + _ = Window.DispatcherQueue.EnqueueOrInvokeAsync(() => Window.InitializeApplication(data)); } /// @@ -475,7 +475,7 @@ private static void AppUnhandledException(Exception ex, bool shouldShowNotificat userSettingsService.AppSettingsService.RestoreTabsOnStartup = true; userSettingsService.GeneralSettingsService.LastCrashedTabList = lastSessionTabList; - Window.DispatcherQueue.EnqueueAsync(async () => + Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { await Launcher.LaunchUriAsync(new Uri("files-uwp:")); }).Wait(1000); diff --git a/src/Files.App/BaseLayout.cs b/src/Files.App/BaseLayout.cs index b0175aa677f9..5bca9bfae7a1 100644 --- a/src/Files.App/BaseLayout.cs +++ b/src/Files.App/BaseLayout.cs @@ -257,7 +257,7 @@ internal set if (selectedItems.Count == 1) { SelectedItemsPropertiesViewModel.SelectedItemsCountString = $"{selectedItems.Count} {"ItemSelected/Text".GetLocalizedResource()}"; - DispatcherQueue.EnqueueAsync(async () => + DispatcherQueue.EnqueueOrInvokeAsync(async () => { // Tapped event must be executed first await Task.Delay(50); @@ -1355,7 +1355,7 @@ protected async void ValidateItemNameInputText(TextBox textBox, TextBoxBeforeTex { args.Cancel = true; - await DispatcherQueue.EnqueueAsync(() => + await DispatcherQueue.EnqueueOrInvokeAsync(() => { var oldSelection = textBox.SelectionStart + textBox.SelectionLength; var oldText = textBox.Text; diff --git a/src/Files.App/DataModels/NavigationControlItems/DriveItem.cs b/src/Files.App/DataModels/NavigationControlItems/DriveItem.cs index 26f70f183bb6..13174508dec2 100644 --- a/src/Files.App/DataModels/NavigationControlItems/DriveItem.cs +++ b/src/Files.App/DataModels/NavigationControlItems/DriveItem.cs @@ -184,7 +184,7 @@ public static async Task CreateFromPropertiesAsync(StorageFolder root item.DeviceID = deviceId; item.Root = root; - _ = App.Window.DispatcherQueue.EnqueueAsync(() => item.UpdatePropertiesAsync()); + _ = App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => item.UpdatePropertiesAsync()); return item; } diff --git a/src/Files.App/DataModels/NavigationControlItems/LocationItem.cs b/src/Files.App/DataModels/NavigationControlItems/LocationItem.cs index ba486e88a133..9f1ab9a42163 100644 --- a/src/Files.App/DataModels/NavigationControlItems/LocationItem.cs +++ b/src/Files.App/DataModels/NavigationControlItems/LocationItem.cs @@ -95,7 +95,7 @@ public ulong SpaceUsed { SetProperty(ref spaceUsed, value); - App.Window.DispatcherQueue.EnqueueAsync(() => OnPropertyChanged(nameof(ToolTipText))); + App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => OnPropertyChanged(nameof(ToolTipText))); } } diff --git a/src/Files.App/DataModels/SidebarPinnedModel.cs b/src/Files.App/DataModels/SidebarPinnedModel.cs index b10e9467c0ae..8ac8515cd2cf 100644 --- a/src/Files.App/DataModels/SidebarPinnedModel.cs +++ b/src/Files.App/DataModels/SidebarPinnedModel.cs @@ -115,7 +115,7 @@ public async Task CreateLocationItemFromPathAsync(string path) { var iconData = await FileThumbnailHelper.LoadIconFromStorageItemAsync(res.Result, 96u, ThumbnailMode.ListView); locationItem.IconData = iconData; - locationItem.Icon = await App.Window.DispatcherQueue.EnqueueAsync(() => locationItem.IconData.ToBitmapAsync()); + locationItem.Icon = await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => locationItem.IconData.ToBitmapAsync()); } if (locationItem.IconData is null) @@ -123,12 +123,12 @@ public async Task CreateLocationItemFromPathAsync(string path) locationItem.IconData = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(path, 96u); if (locationItem.IconData is not null) - locationItem.Icon = await App.Window.DispatcherQueue.EnqueueAsync(() => locationItem.IconData.ToBitmapAsync()); + locationItem.Icon = await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => locationItem.IconData.ToBitmapAsync()); } } else { - locationItem.Icon = await App.Window.DispatcherQueue.EnqueueAsync(() => UIHelpers.GetSidebarIconResource(Constants.ImageRes.Folder)); + locationItem.Icon = await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => UIHelpers.GetSidebarIconResource(Constants.ImageRes.Folder)); locationItem.IsInvalid = true; Debug.WriteLine($"Pinned item was invalid {res.ErrorCode}, item: {path}"); } diff --git a/src/Files.App/Extensions/DispatcherQueueExtensions.cs b/src/Files.App/Extensions/DispatcherQueueExtensions.cs new file mode 100644 index 000000000000..fce0d87b61ad --- /dev/null +++ b/src/Files.App/Extensions/DispatcherQueueExtensions.cs @@ -0,0 +1,48 @@ +using CommunityToolkit.WinUI; +using Microsoft.UI.Dispatching; +using System; +using System.Threading.Tasks; + +namespace Files.App.Extensions +{ + // Window.DispatcherQueue seems to be null sometimes. + // We don't know why, but as a workaround, we invoke the function directly if DispatcherQueue is null. + public static class DispatcherQueueExtensions + { + public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Func function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + { + if (dispatcher is not null) + return dispatcher.EnqueueAsync(function, priority); + else + return function(); + } + + public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Func> function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + { + if (dispatcher is not null) + return dispatcher.EnqueueAsync(function, priority); + else + return function(); + } + + public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Action function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + { + if (dispatcher is not null) + return dispatcher.EnqueueAsync(function, priority); + else + { + function(); + return Task.CompletedTask; + } + } + + public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Func function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + { + if (dispatcher is not null) + return dispatcher.EnqueueAsync(function, priority); + else + return Task.FromResult(function()); + } + + } +} diff --git a/src/Files.App/Filesystem/Cloud/CloudDrivesManager.cs b/src/Files.App/Filesystem/Cloud/CloudDrivesManager.cs index b7db74982556..42e850b2be4d 100644 --- a/src/Files.App/Filesystem/Cloud/CloudDrivesManager.cs +++ b/src/Files.App/Filesystem/Cloud/CloudDrivesManager.cs @@ -1,6 +1,7 @@ using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.WinUI; using Files.App.DataModels.NavigationControlItems; +using Files.App.Extensions; using Files.App.Helpers; using Files.Shared; using Files.Shared.Cloud; @@ -53,7 +54,7 @@ public async Task UpdateDrivesAsync() try { cloudProviderItem.Root = await StorageFolder.GetFolderFromPathAsync(cloudProviderItem.Path); - _ = App.Window.DispatcherQueue.EnqueueAsync(() => cloudProviderItem.UpdatePropertiesAsync()); + _ = App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => cloudProviderItem.UpdatePropertiesAsync()); } catch (Exception ex) { @@ -72,7 +73,7 @@ public async Task UpdateDrivesAsync() { cloudProviderItem.IconData = iconData; await App.Window.DispatcherQueue - .EnqueueAsync(async () => cloudProviderItem.Icon = await iconData.ToBitmapAsync()); + .EnqueueOrInvokeAsync(async () => cloudProviderItem.Icon = await iconData.ToBitmapAsync()); } lock (drives) diff --git a/src/Files.App/Filesystem/Search/FolderSearch.cs b/src/Files.App/Filesystem/Search/FolderSearch.cs index 30b84245e31f..149d49fd93ed 100644 --- a/src/Files.App/Filesystem/Search/FolderSearch.cs +++ b/src/Files.App/Filesystem/Search/FolderSearch.cs @@ -393,7 +393,7 @@ private ListedItem GetListedItemAsync(string itemPath, WIN32_FIND_DATA findData) { if (t.IsCompletedSuccessfully && t.Result is not null) { - _ = FilesystemTasks.Wrap(() => App.Window.DispatcherQueue.EnqueueAsync(async () => + _ = FilesystemTasks.Wrap(() => App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { listedItem.FileImage = await t.Result.ToBitmapAsync(); }, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low)); diff --git a/src/Files.App/Helpers/DynamicDialogFactory.cs b/src/Files.App/Helpers/DynamicDialogFactory.cs index 9aff281a6fde..ee335594a4bd 100644 --- a/src/Files.App/Helpers/DynamicDialogFactory.cs +++ b/src/Files.App/Helpers/DynamicDialogFactory.cs @@ -98,7 +98,7 @@ public static DynamicDialog GetFor_RenameDialog() inputText.Loaded += (s, e) => { // dispatching to the ui thread fixes an issue where the primary dialog button would steal focus - _ = inputText.DispatcherQueue.EnqueueAsync(() => inputText.Focus(FocusState.Programmatic)); + _ = inputText.DispatcherQueue.EnqueueOrInvokeAsync(() => inputText.Focus(FocusState.Programmatic)); ((RenameDialogViewModel)warning.DataContext).IsNameInvalid = true; }; diff --git a/src/Files.App/Helpers/MenuFlyoutHelper.cs b/src/Files.App/Helpers/MenuFlyoutHelper.cs index ff2894b1b99e..88d3e727ee3b 100644 --- a/src/Files.App/Helpers/MenuFlyoutHelper.cs +++ b/src/Files.App/Helpers/MenuFlyoutHelper.cs @@ -1,4 +1,5 @@ using CommunityToolkit.WinUI; +using Files.App.Extensions; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using System; @@ -101,7 +102,7 @@ private static async void SetupItems(MenuFlyout menu) return; } - await menu.DispatcherQueue.EnqueueAsync(() => + await menu.DispatcherQueue.EnqueueOrInvokeAsync(() => { menu.Items.Clear(); AddItems(menu.Items, itemSource); diff --git a/src/Files.App/Helpers/ThemeHelper.cs b/src/Files.App/Helpers/ThemeHelper.cs index 9402afa5afb6..11e2b52a06ff 100644 --- a/src/Files.App/Helpers/ThemeHelper.cs +++ b/src/Files.App/Helpers/ThemeHelper.cs @@ -75,7 +75,7 @@ private static async void UiSettings_ColorValuesChanged(UISettings sender, objec titleBar = App.GetAppWindow(currentApplicationWindow)?.TitleBar; // Dispatch on UI thread so that we have a current appbar to access and change - await currentApplicationWindow.DispatcherQueue.EnqueueAsync(ApplyTheme); + await currentApplicationWindow.DispatcherQueue.EnqueueOrInvokeAsync(ApplyTheme); } private static void ApplyTheme() diff --git a/src/Files.App/Interacts/BaseLayoutCommandImplementationModel.cs b/src/Files.App/Interacts/BaseLayoutCommandImplementationModel.cs index 116f2a9658e5..0dc8e224f82c 100644 --- a/src/Files.App/Interacts/BaseLayoutCommandImplementationModel.cs +++ b/src/Files.App/Interacts/BaseLayoutCommandImplementationModel.cs @@ -100,7 +100,7 @@ public virtual async void OpenDirectoryInNewTab(RoutedEventArgs e) { foreach (ListedItem listedItem in SlimContentPage.SelectedItems) { - await App.Window.DispatcherQueue.EnqueueAsync(async () => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { await mainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), (listedItem as ShortcutItem)?.TargetPath ?? listedItem.ItemPath); }, diff --git a/src/Files.App/ServicesImplementation/RemovableDrivesService.cs b/src/Files.App/ServicesImplementation/RemovableDrivesService.cs index cb333fc91fdb..41dd2f4ff03e 100644 --- a/src/Files.App/ServicesImplementation/RemovableDrivesService.cs +++ b/src/Files.App/ServicesImplementation/RemovableDrivesService.cs @@ -1,5 +1,6 @@ using CommunityToolkit.WinUI; using Files.App.DataModels.NavigationControlItems; +using Files.App.Extensions; using Files.App.Filesystem; using Files.App.Helpers; using Files.App.Storage.WindowsStorage; @@ -66,7 +67,7 @@ public async Task UpdateDrivePropertiesAsync(ILocatableFolder drive) var rootModified = await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(drive.Path).AsTask()); if (rootModified && drive is DriveItem matchingDriveEjected) { - _ = App.Window.DispatcherQueue.EnqueueAsync(() => + _ = App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => { matchingDriveEjected.Root = rootModified.Result; matchingDriveEjected.Text = rootModified.Result.DisplayName; diff --git a/src/Files.App/ServicesImplementation/ThreadingService.cs b/src/Files.App/ServicesImplementation/ThreadingService.cs index a0a01ebd69e1..c646d35cefec 100644 --- a/src/Files.App/ServicesImplementation/ThreadingService.cs +++ b/src/Files.App/ServicesImplementation/ThreadingService.cs @@ -1,4 +1,5 @@ using CommunityToolkit.WinUI; +using Files.App.Extensions; using Files.Backend.Services; using Microsoft.UI.Dispatching; using System; @@ -17,12 +18,12 @@ public ThreadingService() public Task ExecuteOnUiThreadAsync(Action action) { - return _dispatcherQueue.EnqueueAsync(action); + return _dispatcherQueue.EnqueueOrInvokeAsync(action); } public Task ExecuteOnUiThreadAsync(Func func) { - return _dispatcherQueue.EnqueueAsync(func); + return _dispatcherQueue.EnqueueOrInvokeAsync(func); } } } diff --git a/src/Files.App/UserControls/Widgets/DrivesWidget.xaml.cs b/src/Files.App/UserControls/Widgets/DrivesWidget.xaml.cs index 9cdfd58bfb0e..d6bcc00bb94e 100644 --- a/src/Files.App/UserControls/Widgets/DrivesWidget.xaml.cs +++ b/src/Files.App/UserControls/Widgets/DrivesWidget.xaml.cs @@ -61,7 +61,7 @@ public async Task LoadCardThumbnailAsync() // Thumbnail data is valid, set the item icon if (thumbnailData is not null && thumbnailData.Length > 0) - Thumbnail = await thumbnailData.ToBitmapAsync(Constants.Widgets.WidgetIconSize); + Thumbnail = await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => thumbnailData.ToBitmapAsync(Constants.Widgets.WidgetIconSize)); } public int CompareTo(DriveCardItem? other) => Item.Path.CompareTo(other?.Item?.Path); @@ -146,7 +146,7 @@ public DrivesWidget() private async void Drives_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { - await DispatcherQueue.EnqueueAsync(async () => + await DispatcherQueue.EnqueueOrInvokeAsync(async () => { foreach (DriveItem drive in drivesViewModel.Drives.ToList()) { diff --git a/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs b/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs index 5eb1d63d35d2..971d9313fc2e 100644 --- a/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs +++ b/src/Files.App/UserControls/Widgets/QuickAccessWidget.xaml.cs @@ -97,7 +97,7 @@ public async Task LoadCardThumbnailAsync() } if (thumbnailData is not null && thumbnailData.Length > 0) { - Thumbnail = await thumbnailData.ToBitmapAsync(Constants.Widgets.WidgetIconSize); + Thumbnail = await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => thumbnailData.ToBitmapAsync(Constants.Widgets.WidgetIconSize)); } } } @@ -247,7 +247,7 @@ private async void ModifyItem(object? sender, ModifyQuickAccessEventArgs? e) if (e is null) return; - await DispatcherQueue.EnqueueAsync(async () => + await DispatcherQueue.EnqueueOrInvokeAsync(async () => { if (e.Reset) { diff --git a/src/Files.App/UserControls/Widgets/RecentFilesWidget.xaml.cs b/src/Files.App/UserControls/Widgets/RecentFilesWidget.xaml.cs index d6e9e89a469a..577ca12b7e3c 100644 --- a/src/Files.App/UserControls/Widgets/RecentFilesWidget.xaml.cs +++ b/src/Files.App/UserControls/Widgets/RecentFilesWidget.xaml.cs @@ -210,7 +210,7 @@ public async Task RefreshWidget() private async void Manager_RecentFilesChanged(object sender, NotifyCollectionChangedEventArgs e) { - await DispatcherQueue.EnqueueAsync(async () => + await DispatcherQueue.EnqueueOrInvokeAsync(async () => { // e.Action can only be Reset right now; naively refresh everything for simplicity await UpdateRecentsList(e); diff --git a/src/Files.App/ViewModels/ItemViewModel.cs b/src/Files.App/ViewModels/ItemViewModel.cs index 5d94cd9d08f3..5a365075abfc 100644 --- a/src/Files.App/ViewModels/ItemViewModel.cs +++ b/src/Files.App/ViewModels/ItemViewModel.cs @@ -399,7 +399,7 @@ private async void RecycleBinRefreshRequested(object sender, FileSystemEventArgs if (!CommonPaths.RecycleBinPath.Equals(CurrentFolder?.ItemPath, StringComparison.OrdinalIgnoreCase)) return; - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { RefreshItems(null); }); @@ -460,7 +460,7 @@ private async void FolderSizeProvider_SizeChanged(object? sender, SizeChangedEve var matchingItem = filesAndFolders.FirstOrDefault(x => x.ItemPath == e.Path); if (matchingItem is not null) { - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { if (e.ValueState is SizeChangedValueState.None) { @@ -486,7 +486,7 @@ await dispatcherQueue.EnqueueAsync(() => private async void FileTagsSettingsService_OnSettingUpdated(object? sender, EventArgs e) { - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { if (WorkingDirectory != "Home") RefreshItems(null); @@ -506,7 +506,7 @@ private async void UserSettingsService_OnSettingChangedEvent(object? sender, Set case nameof(UserSettingsService.FoldersSettingsService.CalculateFolderSizes): case nameof(UserSettingsService.FoldersSettingsService.SelectFilesOnHover): case nameof(UserSettingsService.FoldersSettingsService.ShowCheckboxesWhenSelectingItems): - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { if (WorkingDirectory != "Home") RefreshItems(null); @@ -516,7 +516,7 @@ await dispatcherQueue.EnqueueAsync(() => case nameof(UserSettingsService.FoldersSettingsService.DefaultGroupOption): case nameof(UserSettingsService.FoldersSettingsService.DefaultSortDirectoriesAlongsideFiles): case nameof(UserSettingsService.FoldersSettingsService.SyncFolderPreferencesAcrossDirectories): - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { folderSettings.OnDefaultPreferencesChanged(WorkingDirectory, e.SettingName); UpdateSortAndGroupOptions(); @@ -553,7 +553,7 @@ public void CancelExtendedPropertiesLoadingForItem(ListedItem item) public async Task ApplySingleFileChangeAsync(ListedItem item) { var newIndex = filesAndFolders.IndexOf(item); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { FilesAndFolders.Remove(item); if (newIndex != -1) @@ -595,7 +595,7 @@ void ClearDisplay() if (NativeWinApiHelper.IsHasThreadAccessPropertyPresent && dispatcherQueue.HasThreadAccess) ClearDisplay(); else - await dispatcherQueue.EnqueueAsync(ClearDisplay); + await dispatcherQueue.EnqueueOrInvokeAsync(ClearDisplay); return; } @@ -681,7 +681,7 @@ void UpdateUI() else { ApplyChanges(); - await dispatcherQueue.EnqueueAsync(UpdateUI); + await dispatcherQueue.EnqueueOrInvokeAsync(UpdateUI); } } catch (Exception ex) @@ -696,7 +696,7 @@ private Task RequestSelectionAsync(List itemsToSelect) if (itemsToSelect is null || itemsToSelect.IsEmpty()) return Task.CompletedTask; - return dispatcherQueue.EnqueueAsync(() => + return dispatcherQueue.EnqueueOrInvokeAsync(() => { OnSelectionRequestedEvent?.Invoke(this, itemsToSelect); }); @@ -800,7 +800,7 @@ await Task.Run(() => if (token.IsCancellationRequested) return; - await dispatcherQueue.EnqueueAsync( + await dispatcherQueue.EnqueueOrInvokeAsync( FilesAndFolders.EndBulkOperation); } catch (Exception ex) @@ -824,7 +824,7 @@ public Task ReloadItemGroupHeaderImagesAsync() foreach (var gp in FilesAndFolders.GroupedCollection.ToList()) { var img = await GetItemTypeGroupIcon(gp.FirstOrDefault()); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { gp.Model.ImageSource = img; }, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low); @@ -898,7 +898,7 @@ private async Task LoadItemThumbnail(ListedItem item, uint thumbnailSize = 96, I if (!(Thumbnail is null || Thumbnail.Size == 0 || Thumbnail.OriginalHeight == 0 || Thumbnail.OriginalWidth == 0)) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.FileImage ??= new BitmapImage(); item.FileImage.DecodePixelType = DecodePixelType.Logical; @@ -917,7 +917,7 @@ await dispatcherQueue.EnqueueAsync(async () => var overlayInfo = await FileThumbnailHelper.LoadOverlayAsync(item.ItemPath, thumbnailSize); if (overlayInfo is not null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.IconOverlay = await overlayInfo.ToBitmapAsync(); item.ShieldIcon = await GetShieldIcon(); @@ -931,7 +931,7 @@ await dispatcherQueue.EnqueueAsync(async () => var iconInfo = await FileThumbnailHelper.LoadIconAndOverlayAsync(item.ItemPath, thumbnailSize, false); if (iconInfo.IconData is not null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.FileImage = await iconInfo.IconData.ToBitmapAsync(); if (!string.IsNullOrEmpty(item.FileExtension) && @@ -945,7 +945,7 @@ await dispatcherQueue.EnqueueAsync(async () => if (iconInfo.OverlayData is not null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.IconOverlay = await iconInfo.OverlayData.ToBitmapAsync(); item.ShieldIcon = await GetShieldIcon(); @@ -968,7 +968,7 @@ await dispatcherQueue.EnqueueAsync(async () => using StorageItemThumbnail Thumbnail = await FilesystemTasks.Wrap(() => matchingStorageFolder.GetThumbnailAsync(thumbnailMode, thumbnailSize, ThumbnailOptions.ReturnOnlyIfCached).AsTask()); if (!(Thumbnail is null || Thumbnail.Size == 0 || Thumbnail.OriginalHeight == 0 || Thumbnail.OriginalWidth == 0)) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.FileImage ??= new BitmapImage(); item.FileImage.DecodePixelType = DecodePixelType.Logical; @@ -981,7 +981,7 @@ await dispatcherQueue.EnqueueAsync(async () => var overlayInfo = await FileThumbnailHelper.LoadOverlayAsync(item.ItemPath, thumbnailSize); if (overlayInfo is not null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.IconOverlay = await overlayInfo.ToBitmapAsync(); item.ShieldIcon = await GetShieldIcon(); @@ -995,7 +995,7 @@ await dispatcherQueue.EnqueueAsync(async () => var iconInfo = await FileThumbnailHelper.LoadIconAndOverlayAsync(item.ItemPath, thumbnailSize, true); if (iconInfo.IconData is not null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.FileImage = await iconInfo.IconData.ToBitmapAsync(); }, Microsoft.UI.Dispatching.DispatcherQueuePriority.Low); @@ -1003,7 +1003,7 @@ await dispatcherQueue.EnqueueAsync(async () => if (iconInfo.OverlayData is not null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { item.IconOverlay = await iconInfo.OverlayData.ToBitmapAsync(); item.ShieldIcon = await GetShieldIcon(); @@ -1069,7 +1069,7 @@ await Task.Run(async () => var itemType = (item.ItemType == "Folder".GetLocalizedResource()) ? item.ItemType : matchingStorageFile.DisplayType; cts.Token.ThrowIfCancellationRequested(); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { item.FolderRelativeId = matchingStorageFile.FolderRelativeId; item.ItemType = itemType; @@ -1100,7 +1100,7 @@ await dispatcherQueue.EnqueueAsync(() => if (matchingStorageFolder.DisplayName != item.Name && !matchingStorageFolder.DisplayName.StartsWith("$R", StringComparison.Ordinal)) { cts.Token.ThrowIfCancellationRequested(); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { item.ItemNameRaw = matchingStorageFolder.DisplayName; }); @@ -1119,7 +1119,7 @@ await dispatcherQueue.EnqueueAsync(() => var itemType = (item.ItemType == "Folder".GetLocalizedResource()) ? item.ItemType : matchingStorageFolder.DisplayType; cts.Token.ThrowIfCancellationRequested(); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { item.FolderRelativeId = matchingStorageFolder.FolderRelativeId; item.ItemType = itemType; @@ -1158,7 +1158,7 @@ await FilesystemTasks.Wrap(async () => { var fileTag = FileTagsHelper.ReadFileTag(item.ItemPath); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { // Reset cloud sync status icon item.SyncStatusUI = new CloudDriveSyncStatusUI(); @@ -1175,7 +1175,7 @@ await dispatcherQueue.EnqueueAsync(() => { cts.Token.ThrowIfCancellationRequested(); await SafetyExtensions.IgnoreExceptions(() => - dispatcherQueue.EnqueueAsync(() => + dispatcherQueue.EnqueueOrInvokeAsync(() => { gp.Model.ImageSource = groupImage; gp.InitializeExtendedGroupHeaderInfoAsync(); @@ -1202,7 +1202,7 @@ await SafetyExtensions.IgnoreExceptions(() => var headerIconInfo = await FileThumbnailHelper.LoadIconWithoutOverlayAsync(item.ItemPath, 64u, false); if (headerIconInfo is not null && !item.IsShortcut) - groupImage = await dispatcherQueue.EnqueueAsync(() => headerIconInfo.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low); + groupImage = await dispatcherQueue.EnqueueOrInvokeAsync(() => headerIconInfo.ToBitmapAsync(), Microsoft.UI.Dispatching.DispatcherQueuePriority.Low); // The groupImage is null if loading icon from fulltrust process failed if (!item.IsShortcut && !item.IsHiddenItem && !FtpHelpers.IsFtpPath(item.ItemPath) && groupImage is null) @@ -1214,7 +1214,7 @@ await SafetyExtensions.IgnoreExceptions(() => using StorageItemThumbnail headerThumbnail = await FilesystemTasks.Wrap(() => matchingStorageItem.GetThumbnailAsync(ThumbnailMode.DocumentsView, 36, ThumbnailOptions.UseCurrentScale).AsTask()); if (headerThumbnail is not null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { var bmp = new BitmapImage(); await bmp.SetSourceAsync(headerThumbnail); @@ -1228,7 +1228,7 @@ await dispatcherQueue.EnqueueAsync(async () => // This prevents both the shortcut glyph and folder icon being shown else if (!item.IsShortcut) { - await dispatcherQueue.EnqueueAsync(() => groupImage = new SvgImageSource(new Uri("ms-appx:///Assets/FolderIcon2.svg")) + await dispatcherQueue.EnqueueOrInvokeAsync(() => groupImage = new SvgImageSource(new Uri("ms-appx:///Assets/FolderIcon2.svg")) { RasterizePixelHeight = 128, RasterizePixelWidth = 128, @@ -1449,7 +1449,7 @@ await Task.Run(async () => { if (!client.IsConnected && await WrappedAutoConnectFtpAsync(client) is null) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { var credentialDialogViewModel = new CredentialDialogViewModel(); @@ -1812,7 +1812,7 @@ private async void DirectoryWatcher_Changed(object sender, FileSystemEventArgs e { Debug.WriteLine($"Directory watcher event: {e.ChangeType}, {e.FullPath}"); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { RefreshItems(null); }); @@ -1832,7 +1832,7 @@ private async void ItemQueryResult_ContentsChanged(IStorageQueryResultBase sende sender.ApplyNewQueryOptions(options); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { RefreshItems(null); }); @@ -2188,7 +2188,7 @@ private async Task UpdateFilesOrFoldersAsync(IEnumerable paths, bool has var matchingItems = filesAndFolders.Where(x => paths.Any(p => p.Equals(x.ItemPath, StringComparison.OrdinalIgnoreCase))); var results = await Task.WhenAll(matchingItems.Select(x => GetFileOrFolderUpdateInfoAsync(x, hasSyncStatus))); - await dispatcherQueue.EnqueueAsync(() => + await dispatcherQueue.EnqueueOrInvokeAsync(() => { foreach (var result in results) { diff --git a/src/Files.App/ViewModels/Previews/BasePreviewModel.cs b/src/Files.App/ViewModels/Previews/BasePreviewModel.cs index d501d132ecc6..05816f9c7a0a 100644 --- a/src/Files.App/ViewModels/Previews/BasePreviewModel.cs +++ b/src/Files.App/ViewModels/Previews/BasePreviewModel.cs @@ -1,6 +1,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.WinUI; +using Files.App.Extensions; using Files.App.Filesystem; using Files.App.Filesystem.StorageItems; using Files.App.Helpers; @@ -98,11 +99,11 @@ public async virtual Task> LoadPreviewAndDetailsAsync() iconData ??= await FileThumbnailHelper.LoadIconWithoutOverlayAsync(Item.ItemPath, 256); if (iconData is not null) { - await App.Window.DispatcherQueue.EnqueueAsync(async () => FileImage = await iconData.ToBitmapAsync()); + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => FileImage = await iconData.ToBitmapAsync()); } else { - FileImage ??= await App.Window.DispatcherQueue.EnqueueAsync(() => new BitmapImage()); + FileImage ??= await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => new BitmapImage()); } return new List(); diff --git a/src/Files.App/ViewModels/Previews/ImagePreviewViewModel.cs b/src/Files.App/ViewModels/Previews/ImagePreviewViewModel.cs index 8f24953a995b..4cfd64a32890 100644 --- a/src/Files.App/ViewModels/Previews/ImagePreviewViewModel.cs +++ b/src/Files.App/ViewModels/Previews/ImagePreviewViewModel.cs @@ -1,4 +1,5 @@ using CommunityToolkit.WinUI; +using Files.App.Extensions; using Files.App.Filesystem; using Files.App.ViewModels.Properties; using Microsoft.UI.Xaml.Media; @@ -33,7 +34,7 @@ public override async Task> LoadPreviewAndDetailsAsync() { using IRandomAccessStream stream = await Item.ItemFile.OpenAsync(FileAccessMode.Read); - await App.Window.DispatcherQueue.EnqueueAsync(async () => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { BitmapImage bitmap = new(); await bitmap.SetSourceAsync(stream); diff --git a/src/Files.App/ViewModels/Previews/PDFPreviewViewModel.cs b/src/Files.App/ViewModels/Previews/PDFPreviewViewModel.cs index bd3fd54439af..e5dceb6d5278 100644 --- a/src/Files.App/ViewModels/Previews/PDFPreviewViewModel.cs +++ b/src/Files.App/ViewModels/Previews/PDFPreviewViewModel.cs @@ -1,4 +1,5 @@ using CommunityToolkit.WinUI; +using Files.App.Extensions; using Files.App.Filesystem; using Files.App.ViewModels.Properties; using Microsoft.UI.Xaml; @@ -91,7 +92,7 @@ private async Task LoadPagesAsync(PdfDocument pdf) BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream); using SoftwareBitmap sw = await decoder.GetSoftwareBitmapAsync(); - await App.Window.DispatcherQueue.EnqueueAsync(async () => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { BitmapImage src = new(); PageViewModel pageData = new() diff --git a/src/Files.App/ViewModels/Properties/BaseProperties.cs b/src/Files.App/ViewModels/Properties/BaseProperties.cs index af8b43725f2c..b1d5d9c233f6 100644 --- a/src/Files.App/ViewModels/Properties/BaseProperties.cs +++ b/src/Files.App/ViewModels/Properties/BaseProperties.cs @@ -92,7 +92,7 @@ public async Task CalculateFolderSizeAsync(string path, CancellationToken if (size > ViewModel.ItemSizeBytes) { - await Dispatcher.EnqueueAsync(() => + await Dispatcher.EnqueueOrInvokeAsync(() => { ViewModel.ItemSizeBytes = size; ViewModel.ItemSize = size.ToSizeString(); diff --git a/src/Files.App/ViewModels/Properties/CustomizationViewModel.cs b/src/Files.App/ViewModels/Properties/CustomizationViewModel.cs index 7bf28e6a7972..6a84d8d45f13 100644 --- a/src/Files.App/ViewModels/Properties/CustomizationViewModel.cs +++ b/src/Files.App/ViewModels/Properties/CustomizationViewModel.cs @@ -12,6 +12,7 @@ using System.IO; using System.Threading.Tasks; using Windows.Storage.Pickers; +using Files.App.Extensions; namespace Files.App.ViewModels.Properties { @@ -107,11 +108,11 @@ private async Task ExecuteRestoreDefaultIconAsync() if (setIconResult) { - await App.Window.DispatcherQueue.EnqueueAsync(() => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => { AppInstance?.FilesystemViewModel?.RefreshItems(null, async () => { - await App.Window.DispatcherQueue.EnqueueAsync(() => RestoreButtonIsEnabled = true); + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => RestoreButtonIsEnabled = true); }); }); @@ -155,7 +156,7 @@ private async Task ChangeIcon(IconFileInfo selectedIconInfo) if (setIconResult) { - await App.Window.DispatcherQueue.EnqueueAsync(() => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => { AppInstance?.FilesystemViewModel?.RefreshItems(null); }); diff --git a/src/Files.App/ViewModels/Properties/FileProperties.cs b/src/Files.App/ViewModels/Properties/FileProperties.cs index 4c5b07b82cc1..de73883b1757 100644 --- a/src/Files.App/ViewModels/Properties/FileProperties.cs +++ b/src/Files.App/ViewModels/Properties/FileProperties.cs @@ -90,7 +90,7 @@ public override void GetBaseProperties() } else { - await App.Window.DispatcherQueue.EnqueueAsync( + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync( () => NavigationHelpers.OpenPathInNewTab(Path.GetDirectoryName(ViewModel.ShortcutItemPath))); } }, diff --git a/src/Files.App/ViewModels/Properties/FolderProperties.cs b/src/Files.App/ViewModels/Properties/FolderProperties.cs index 4f495ad06b26..287b6584deb9 100644 --- a/src/Files.App/ViewModels/Properties/FolderProperties.cs +++ b/src/Files.App/ViewModels/Properties/FolderProperties.cs @@ -65,7 +65,7 @@ public override void GetBaseProperties() ViewModel.ShortcutItemArgumentsVisibility = false; ViewModel.ShortcutItemOpenLinkCommand = new RelayCommand(async () => { - await App.Window.DispatcherQueue.EnqueueAsync( + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync( () => NavigationHelpers.OpenPathInNewTab(Path.GetDirectoryName(Environment.ExpandEnvironmentVariables(ViewModel.ShortcutItemPath)))); }, () => diff --git a/src/Files.App/ViewModels/Properties/HashesViewModel.cs b/src/Files.App/ViewModels/Properties/HashesViewModel.cs index c621d6b41b60..6104487c276e 100644 --- a/src/Files.App/ViewModels/Properties/HashesViewModel.cs +++ b/src/Files.App/ViewModels/Properties/HashesViewModel.cs @@ -83,7 +83,7 @@ private void ToggleIsEnabled(string? algorithm) { hashInfoItem.HashValue = "Calculating".GetLocalizedResource(); - App.Window.DispatcherQueue.EnqueueAsync(async () => + App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { try { diff --git a/src/Files.App/ViewModels/SidebarViewModel.cs b/src/Files.App/ViewModels/SidebarViewModel.cs index 2b35b5275179..1a3a678b397a 100644 --- a/src/Files.App/ViewModels/SidebarViewModel.cs +++ b/src/Files.App/ViewModels/SidebarViewModel.cs @@ -245,7 +245,7 @@ private async void CreateItemHome() private async void Manager_DataChanged(object sender, NotifyCollectionChangedEventArgs e) { - await dispatcherQueue.EnqueueAsync(async () => + await dispatcherQueue.EnqueueOrInvokeAsync(async () => { var sectionType = (sender is SectionType s) ? s : SectionType.Drives; var section = await GetOrCreateSection(sectionType); diff --git a/src/Files.App/ViewModels/ToolbarViewModel.cs b/src/Files.App/ViewModels/ToolbarViewModel.cs index 7a19b0bd4c84..58e1639f3baf 100644 --- a/src/Files.App/ViewModels/ToolbarViewModel.cs +++ b/src/Files.App/ViewModels/ToolbarViewModel.cs @@ -488,7 +488,7 @@ public async void PathBoxItem_Tapped(object sender, TappedRoutedEventArgs e) if (pointerRoutedEventArgs is not null) { - await App.Window.DispatcherQueue.EnqueueAsync(async () => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { await mainPageViewModel.AddNewTabByPathAsync(typeof(PaneHolderPage), itemTappedPath); }, DispatcherQueuePriority.Low); diff --git a/src/Files.App/Views/BaseShellPage.cs b/src/Files.App/Views/BaseShellPage.cs index 1bc79ec610a1..09b3dee6de85 100644 --- a/src/Files.App/Views/BaseShellPage.cs +++ b/src/Files.App/Views/BaseShellPage.cs @@ -628,7 +628,7 @@ protected async void DisplayFilesystemConsentDialog() if (drivesViewModel?.ShowUserConsentOnInit ?? false) { drivesViewModel.ShowUserConsentOnInit = false; - await DispatcherQueue.EnqueueAsync(async () => + await DispatcherQueue.EnqueueOrInvokeAsync(async () => { var dialog = DynamicDialogFactory.GetFor_ConsentDialog(); await SetContentDialogRoot(dialog).ShowAsync(ContentDialogPlacement.Popup); diff --git a/src/Files.App/Views/Properties/GeneralPage.xaml.cs b/src/Files.App/Views/Properties/GeneralPage.xaml.cs index eeaa4783a521..b213b7adf414 100644 --- a/src/Files.App/Views/Properties/GeneralPage.xaml.cs +++ b/src/Files.App/Views/Properties/GeneralPage.xaml.cs @@ -1,5 +1,6 @@ using CommunityToolkit.WinUI; using Files.App.DataModels.NavigationControlItems; +using Files.App.Extensions; using Files.App.Filesystem; using Files.App.Helpers; using Files.App.Shell; @@ -55,7 +56,7 @@ bool SaveDrive(DriveItem drive) newName = letterRegex.Replace(newName, string.Empty); // Remove "(C:)" from the new label Win32API.SetVolumeLabel(drive.Path, newName); - _ = App.Window.DispatcherQueue.EnqueueAsync(async () => + _ = App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { await drive.UpdateLabelAsync(); await fsVM.SetWorkingDirectoryAsync(drive.Path); @@ -76,7 +77,7 @@ async Task SaveLibraryAsync(LibraryItem library) if (renamed is ReturnResult.Success) { var newPath = Path.Combine(Path.GetDirectoryName(library.ItemPath)!, newName); - _ = App.Window.DispatcherQueue.EnqueueAsync(async () => + _ = App.Window.DispatcherQueue.EnqueueOrInvokeAsync(async () => { await fsVM.SetWorkingDirectoryAsync(newPath); }); @@ -94,7 +95,7 @@ async Task SaveCombinedAsync(IList fileOrFolders) { foreach (var fileOrFolder in fileOrFolders) { - await App.Window.DispatcherQueue.EnqueueAsync(() => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => UIFilesystemHelpers.SetHiddenAttributeItem(fileOrFolder, ViewModel.IsHidden, itemMM) ); } @@ -108,7 +109,7 @@ async Task SaveBaseAsync(ListedItem item) var itemMM = AppInstance?.SlimContentPage?.ItemManipulationModel; if (itemMM is not null) // null on homepage { - await App.Window.DispatcherQueue.EnqueueAsync(() => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => UIFilesystemHelpers.SetHiddenAttributeItem(item, ViewModel.IsHidden, itemMM) ); } @@ -116,7 +117,7 @@ await App.Window.DispatcherQueue.EnqueueAsync(() => if (!GetNewName(out var newName)) return true; - return await App.Window.DispatcherQueue.EnqueueAsync(() => + return await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => UIFilesystemHelpers.RenameFileItemAsync(item, ViewModel.ItemName, AppInstance, false) ); } diff --git a/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs b/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs index abafb13049c5..d3d6485d1ffe 100644 --- a/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs +++ b/src/Files.App/Views/Properties/MainPropertiesPage.xaml.cs @@ -89,7 +89,7 @@ private async void Page_Loaded(object sender, RoutedEventArgs e) DragZoneHelper.SetDragZones(Window, (int)TitlebarArea.ActualHeight); AppWindow.Destroying += AppWindow_Destroying; - await App.Window.DispatcherQueue.EnqueueAsync(() => AppSettings.UpdateThemeElements.Execute(null)); + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => AppSettings.UpdateThemeElements.Execute(null)); } else { @@ -116,7 +116,7 @@ private void UpdateDialogLayout() private async void AppSettings_ThemeModeChanged(object? sender, EventArgs e) { - await DispatcherQueue.EnqueueAsync(() => + await DispatcherQueue.EnqueueOrInvokeAsync(() => { ((Frame)Parent).RequestedTheme = ThemeHelper.RootTheme; diff --git a/src/Files.App/Views/Properties/SecurityAdvancedPage.xaml.cs b/src/Files.App/Views/Properties/SecurityAdvancedPage.xaml.cs index b5bbe0f78ce7..a185465a7535 100644 --- a/src/Files.App/Views/Properties/SecurityAdvancedPage.xaml.cs +++ b/src/Files.App/Views/Properties/SecurityAdvancedPage.xaml.cs @@ -67,7 +67,7 @@ private async void SecurityAdvancedPage_Loaded(object sender, RoutedEventArgs e) appWindow.Destroying += AppWindow_Destroying; // Update theme - await App.Window.DispatcherQueue.EnqueueAsync(() => AppSettings.UpdateThemeElements.Execute(null)); + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => AppSettings.UpdateThemeElements.Execute(null)); } } @@ -81,7 +81,7 @@ private async void AppSettings_ThemeModeChanged(object sender, EventArgs e) { var selectedTheme = ThemeHelper.RootTheme; - await DispatcherQueue.EnqueueAsync(() => + await DispatcherQueue.EnqueueOrInvokeAsync(() => { ((Frame)Parent).RequestedTheme = selectedTheme; diff --git a/src/Files.App/Views/Properties/SecurityPage.xaml.cs b/src/Files.App/Views/Properties/SecurityPage.xaml.cs index 996328c2e071..e044e0759ad6 100644 --- a/src/Files.App/Views/Properties/SecurityPage.xaml.cs +++ b/src/Files.App/Views/Properties/SecurityPage.xaml.cs @@ -127,7 +127,7 @@ private async void SecurityAdvancedPageWindow_Destroying(AppWindow sender, objec if (SecurityViewModel is not null) { // Reload permissions when closing - await DispatcherQueue.EnqueueAsync(() => SecurityViewModel.GetAccessControlList()); + await DispatcherQueue.EnqueueOrInvokeAsync(() => SecurityViewModel.GetAccessControlList()); } } diff --git a/src/Files.App/Views/Properties/ShortcutPage.xaml.cs b/src/Files.App/Views/Properties/ShortcutPage.xaml.cs index b53452eef11d..58ffd6efa5e4 100644 --- a/src/Files.App/Views/Properties/ShortcutPage.xaml.cs +++ b/src/Files.App/Views/Properties/ShortcutPage.xaml.cs @@ -1,4 +1,5 @@ using CommunityToolkit.WinUI; +using Files.App.Extensions; using Files.App.Filesystem; using Files.App.Helpers; using Files.App.ViewModels.Properties; @@ -25,7 +26,7 @@ public override async Task SaveChangesAsync() if (shortcutItem is null) return true; - await App.Window.DispatcherQueue.EnqueueAsync(() => + await App.Window.DispatcherQueue.EnqueueOrInvokeAsync(() => UIFilesystemHelpers.UpdateShortcutItemProperties(shortcutItem, ViewModel.ShortcutItemPath, ViewModel.ShortcutItemArguments, From 2ffecca99d4110ac1f925564b9f6705564e75ca9 Mon Sep 17 00:00:00 2001 From: hishitetsu <66369541+hishitetsu@users.noreply.github.com> Date: Tue, 25 Apr 2023 22:45:15 +0900 Subject: [PATCH 2/2] Nullable --- src/Files.App/Extensions/DispatcherQueueExtensions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Files.App/Extensions/DispatcherQueueExtensions.cs b/src/Files.App/Extensions/DispatcherQueueExtensions.cs index fce0d87b61ad..a410d3315b16 100644 --- a/src/Files.App/Extensions/DispatcherQueueExtensions.cs +++ b/src/Files.App/Extensions/DispatcherQueueExtensions.cs @@ -9,7 +9,7 @@ namespace Files.App.Extensions // We don't know why, but as a workaround, we invoke the function directly if DispatcherQueue is null. public static class DispatcherQueueExtensions { - public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Func function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + public static Task EnqueueOrInvokeAsync(this DispatcherQueue? dispatcher, Func function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) { if (dispatcher is not null) return dispatcher.EnqueueAsync(function, priority); @@ -17,7 +17,7 @@ public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Func EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Func> function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + public static Task EnqueueOrInvokeAsync(this DispatcherQueue? dispatcher, Func> function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) { if (dispatcher is not null) return dispatcher.EnqueueAsync(function, priority); @@ -25,7 +25,7 @@ public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, F return function(); } - public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Action function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + public static Task EnqueueOrInvokeAsync(this DispatcherQueue? dispatcher, Action function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) { if (dispatcher is not null) return dispatcher.EnqueueAsync(function, priority); @@ -36,7 +36,7 @@ public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Action } } - public static Task EnqueueOrInvokeAsync(this DispatcherQueue dispatcher, Func function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) + public static Task EnqueueOrInvokeAsync(this DispatcherQueue? dispatcher, Func function, DispatcherQueuePriority priority = DispatcherQueuePriority.Normal) { if (dispatcher is not null) return dispatcher.EnqueueAsync(function, priority);