Skip to content

Commit

Permalink
删除 ThreadSwitcher 使用前的判断
Browse files Browse the repository at this point in the history
因为它自己会判断
  • Loading branch information
wherewhere committed Nov 12, 2023
1 parent 861ed52 commit 50e1549
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 104 deletions.
67 changes: 46 additions & 21 deletions CoreAppUWP/Common/ThreadSwitcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,55 @@

namespace CoreAppUWP.Common
{
/// <summary>
/// The interface of helper type for switch thread.
/// </summary>
public interface IThreadSwitcher : INotifyCompletion
{
/// <summary>
/// Gets a value that indicates whether the asynchronous operation has completed.
/// </summary>
bool IsCompleted => true;

/// <summary>
/// Ends the await on the completed task.
/// </summary>
void GetResult() { }

/// <summary>
/// Gets an awaiter used to await this <see cref="IThreadSwitcher"/>.
/// </summary>
/// <returns>An awaiter instance.</returns>
IThreadSwitcher GetAwaiter();
}

/// <summary>
/// A helper type for switch thread by <see cref="CoreDispatcher"/>. This type is not intended to be used directly from your code.
/// </summary>
/// <param name="Dispatcher">A <see cref="CoreDispatcher"/> whose foreground thread to switch execution to.</param>
/// <param name="Priority">Specifies the priority for event dispatch.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public readonly record struct DispatcherThreadSwitcher(CoreDispatcher Dispatcher, CoreDispatcherPriority Priority = CoreDispatcherPriority.Normal) : INotifyCompletion
public readonly record struct CoreDispatcherThreadSwitcher(CoreDispatcher Dispatcher, CoreDispatcherPriority Priority = CoreDispatcherPriority.Normal) : IThreadSwitcher
{
/// <summary>
/// Gets a value that indicates whether the asynchronous operation has completed.
/// </summary>
public bool IsCompleted => Dispatcher.HasThreadAccess;
public bool IsCompleted => Dispatcher?.HasThreadAccess != false;

/// <summary>
/// Ends the await on the completed task.
/// </summary>
/// <inheritdoc/>
public void GetResult() { }

/// <summary>
/// Gets an awaiter used to await this <see cref="DispatcherThreadSwitcher"/>.
/// Gets an awaiter used to await this <see cref="CoreDispatcherThreadSwitcher"/>.
/// </summary>
/// <returns>An awaiter instance.</returns>
public DispatcherThreadSwitcher GetAwaiter() => this;
public CoreDispatcherThreadSwitcher GetAwaiter() => this;

/// <inheritdoc/>
IThreadSwitcher IThreadSwitcher.GetAwaiter() => this;

/// <inheritdoc/>
public void OnCompleted(Action continuation) => _ = Dispatcher.RunAsync(Priority, () => continuation());
public void OnCompleted(Action continuation) => _ = Dispatcher?.RunAsync(Priority, () => continuation());
}

/// <summary>
Expand All @@ -43,51 +66,53 @@ public void GetResult() { }
/// <param name="Dispatcher">A <see cref="DispatcherQueue"/> whose foreground thread to switch execution to.</param>
/// <param name="Priority">Specifies the priority for event dispatch.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public readonly record struct DispatcherQueueThreadSwitcher(DispatcherQueue Dispatcher, DispatcherQueuePriority Priority = DispatcherQueuePriority.Normal) : INotifyCompletion
public readonly record struct DispatcherQueueThreadSwitcher(DispatcherQueue Dispatcher, DispatcherQueuePriority Priority = DispatcherQueuePriority.Normal) : IThreadSwitcher
{
/// <summary>
/// Gets a value that indicates whether the asynchronous operation has completed.
/// </summary>
public bool IsCompleted => Dispatcher.HasThreadAccess;
public bool IsCompleted => Dispatcher?.HasThreadAccess != false;

/// <summary>
/// Ends the await on the completed task.
/// </summary>
/// <inheritdoc/>
public void GetResult() { }

/// <summary>
/// Gets an awaiter used to await this <see cref="DispatcherThreadSwitcher"/>.
/// Gets an awaiter used to await this <see cref="DispatcherQueueThreadSwitcher"/>.
/// </summary>
/// <returns>An awaiter instance.</returns>
public DispatcherQueueThreadSwitcher GetAwaiter() => this;

/// <inheritdoc/>
public void OnCompleted(Action continuation) => _ = Dispatcher.TryEnqueue(Priority, () => continuation());
IThreadSwitcher IThreadSwitcher.GetAwaiter() => this;

/// <inheritdoc/>
public void OnCompleted(Action continuation) => _ = Dispatcher?.TryEnqueue(Priority, () => continuation());
}

/// <summary>
/// A helper type for switch thread by <see cref="ThreadPool"/>. This type is not intended to be used directly from your code.
/// </summary>
/// <param name="Priority">Specifies the priority for event dispatch.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public readonly record struct ThreadPoolThreadSwitcher(WorkItemPriority Priority = WorkItemPriority.Normal) : INotifyCompletion
public readonly record struct ThreadPoolThreadSwitcher(WorkItemPriority Priority = WorkItemPriority.Normal) : IThreadSwitcher
{
/// <summary>
/// Gets a value that indicates whether the asynchronous operation has completed.
/// </summary>
public bool IsCompleted => SynchronizationContext.Current == null;

/// <summary>
/// Ends the await on the completed task.
/// </summary>
/// <inheritdoc/>
public void GetResult() { }

/// <summary>
/// Gets an awaiter used to await this <see cref="DispatcherThreadSwitcher"/>.
/// Gets an awaiter used to await this <see cref="ThreadPoolThreadSwitcher"/>.
/// </summary>
/// <returns>An awaiter instance.</returns>
public ThreadPoolThreadSwitcher GetAwaiter() => this;

/// <inheritdoc/>
IThreadSwitcher IThreadSwitcher.GetAwaiter() => this;

/// <inheritdoc/>
public void OnCompleted(Action continuation) => _ = ThreadPool.RunAsync(_ => continuation(), Priority);
}
Expand All @@ -111,7 +136,7 @@ public static class ThreadSwitcher
/// <param name="dispatcher">A <see cref="CoreDispatcher"/> whose foreground thread to switch execution to.</param>
/// <param name="priority">Specifies the priority for event dispatch.</param>
/// <returns>An object that you can <see langword="await"/>.</returns>
public static DispatcherThreadSwitcher ResumeForegroundAsync(this CoreDispatcher dispatcher, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) => new(dispatcher, priority);
public static CoreDispatcherThreadSwitcher ResumeForegroundAsync(this CoreDispatcher dispatcher, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) => new(dispatcher, priority);

/// <summary>
/// A helper function—for use within a coroutine—that returns control to the caller, and then immediately resumes execution on a thread pool thread.
Expand Down
10 changes: 2 additions & 8 deletions CoreAppUWP/Helpers/BackdropHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,19 +308,13 @@ public static void SetAllBackdrop(BackdropType type)
{
ActiveWindows.Values.ForEach(async x =>
{
if (x.window.DispatcherQueue?.HasThreadAccess == false)
{
await x.window.DispatcherQueue.ResumeForegroundAsync();
}
await x.window.DispatcherQueue.ResumeForegroundAsync();
x.SetBackdrop(type);
});

ActiveDesktopWindows.Values.ForEach(async x =>
{
if (x.desktopWindow.DispatcherQueue?.HasThreadAccess == false)
{
await x.desktopWindow.DispatcherQueue.ResumeForegroundAsync();
}
await x.desktopWindow.DispatcherQueue.ResumeForegroundAsync();
x.SetBackdrop(type);
});
}
Expand Down
85 changes: 25 additions & 60 deletions CoreAppUWP/Helpers/ThemeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static ElementTheme GetActualTheme(Window window) =>
window == null
? SettingsHelper.Get<ElementTheme>(SettingsHelper.SelectedAppTheme)
: window.DispatcherQueue?.HasThreadAccess == false
? window.DispatcherQueue?.EnqueueAsync(() =>
? window.DispatcherQueue.EnqueueAsync(() =>
window.Content is FrameworkElement _rootElement
&& _rootElement.RequestedTheme != ElementTheme.Default
? _rootElement.RequestedTheme
Expand All @@ -60,7 +60,7 @@ public static async ValueTask<ElementTheme> GetActualThemeAsync(Window window) =
window == null
? SettingsHelper.Get<ElementTheme>(SettingsHelper.SelectedAppTheme)
: window.DispatcherQueue?.HasThreadAccess == false
? await window.DispatcherQueue?.EnqueueAsync(() =>
? await window.DispatcherQueue.EnqueueAsync(() =>
window.Content is FrameworkElement _rootElement
&& _rootElement.RequestedTheme != ElementTheme.Default
? _rootElement.RequestedTheme
Expand Down Expand Up @@ -90,41 +90,37 @@ public static ElementTheme GetRootTheme() =>
public static ElementTheme GetRootTheme(Window window) =>
window == null
? ElementTheme.Default
: window.DispatcherQueue.HasThreadAccess
? window.Content is FrameworkElement rootElement
? rootElement.RequestedTheme
: ElementTheme.Default
: window.DispatcherQueue.EnqueueAsync(() =>
: window.DispatcherQueue?.HasThreadAccess == false
? window.DispatcherQueue.EnqueueAsync(() =>
window.Content is FrameworkElement _rootElement
? _rootElement.RequestedTheme
: ElementTheme.Default,
DispatcherQueuePriority.High).AwaitByTaskCompleteSource();
DispatcherQueuePriority.High).AwaitByTaskCompleteSource()
: window.Content is FrameworkElement rootElement
? rootElement.RequestedTheme
: ElementTheme.Default;

public static ValueTask<ElementTheme> GetRootThemeAsync() =>
GetRootThemeAsync(Window.Current ?? CurrentApplicationWindow);

public static async ValueTask<ElementTheme> GetRootThemeAsync(Window window) =>
window == null
? ElementTheme.Default
: window.DispatcherQueue.HasThreadAccess
? window.Content is FrameworkElement rootElement
? rootElement.RequestedTheme
: ElementTheme.Default
: await window.DispatcherQueue.EnqueueAsync(() =>
: window.DispatcherQueue?.HasThreadAccess == false
? await window.DispatcherQueue.EnqueueAsync(() =>
window.Content is FrameworkElement _rootElement
? _rootElement.RequestedTheme
: ElementTheme.Default,
DispatcherQueuePriority.High);
DispatcherQueuePriority.High)
: window.Content is FrameworkElement rootElement
? rootElement.RequestedTheme
: ElementTheme.Default;

public static async void SetRootTheme(ElementTheme value)
{
WindowHelper.ActiveWindows.Values.ForEach(async window =>
{
if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
if (window.Content is FrameworkElement rootElement)
{
rootElement.RequestedTheme = value;
Expand All @@ -133,11 +129,7 @@ public static async void SetRootTheme(ElementTheme value)

WindowHelper.ActiveDesktopWindows.Values.ForEach(async window =>
{
if (!window.DispatcherQueue.HasThreadAccess)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
if (window.Content is FrameworkElement rootElement)
{
rootElement.RequestedTheme = value;
Expand All @@ -153,11 +145,7 @@ public static async ValueTask SetRootThemeAsync(ElementTheme value)
{
await Task.WhenAll(WindowHelper.ActiveWindows.Values.Select(async window =>
{
if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
if (window.Content is FrameworkElement rootElement)
{
rootElement.RequestedTheme = value;
Expand All @@ -166,11 +154,7 @@ await Task.WhenAll(WindowHelper.ActiveWindows.Values.Select(async window =>

await Task.WhenAll(WindowHelper.ActiveDesktopWindows.Values.Select(async window =>
{
if (!window.DispatcherQueue.HasThreadAccess)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
if (window.Content is FrameworkElement rootElement)
{
rootElement.RequestedTheme = value;
Expand All @@ -191,6 +175,7 @@ public static void Initialize()
RootTheme = SettingsHelper.Get<ElementTheme>(SettingsHelper.SelectedAppTheme);

// Registering to color changes, thus we notice when user changes theme system wide
UISettings.ColorValuesChanged -= UISettings_ColorValuesChanged;
UISettings.ColorValuesChanged += UISettings_ColorValuesChanged;
}

Expand Down Expand Up @@ -259,21 +244,15 @@ public static void UpdateExtendViewIntoTitleBar(bool IsExtendsTitleBar)
{
WindowHelper.ActiveWindows.Values.ForEach(async window =>
{
if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = IsExtendsTitleBar;
});

if (!AppWindowTitleBar.IsCustomizationSupported()) { return; }

WindowHelper.ActiveDesktopWindows.Values.ForEach(async window =>
{
if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
window.ExtendsContentIntoTitleBar = IsExtendsTitleBar;
});
}
Expand All @@ -288,11 +267,7 @@ public static async void UpdateSystemCaptionButtonColors()

WindowHelper.ActiveWindows.Values.ForEach(async window =>
{
if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
bool ExtendViewIntoTitleBar = CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar;
ApplicationViewTitleBar TitleBar = ApplicationView.GetForCurrentView().TitleBar;
TitleBar.ForegroundColor = TitleBar.ButtonForegroundColor = ForegroundColor;
Expand All @@ -304,11 +279,7 @@ public static async void UpdateSystemCaptionButtonColors()

WindowHelper.ActiveDesktopWindows.Values.ForEach(async window =>
{
if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();
bool ExtendViewIntoTitleBar = window.ExtendsContentIntoTitleBar;
AppWindowTitleBar TitleBar = window.AppWindow.TitleBar;
TitleBar.ForegroundColor = TitleBar.ButtonForegroundColor = ForegroundColor;
Expand All @@ -319,10 +290,7 @@ public static async void UpdateSystemCaptionButtonColors()

public static async void UpdateSystemCaptionButtonColors(Window window)
{
if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();

bool IsDark = window?.Content is FrameworkElement rootElement ? rootElement.RequestedTheme.IsDarkTheme() : await IsDarkThemeAsync();
bool IsHighContrast = AccessibilitySettings.HighContrast;
Expand All @@ -341,10 +309,7 @@ public static async void UpdateSystemCaptionButtonColors(DesktopWindow window)
{
if (!AppWindowTitleBar.IsCustomizationSupported()) { return; }

if (window.DispatcherQueue?.HasThreadAccess == false)
{
await window.DispatcherQueue.ResumeForegroundAsync();
}
await window.DispatcherQueue.ResumeForegroundAsync();

bool IsDark = window?.Content is FrameworkElement rootElement ? rootElement.RequestedTheme.IsDarkTheme() : await IsDarkThemeAsync();
bool IsHighContrast = AccessibilitySettings.HighContrast;
Expand Down
4 changes: 1 addition & 3 deletions CoreAppUWP/Pages/SettingsPages/SettingsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,7 @@ void OnLaunched(DesktopWindowXamlSource source)
private async void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
string tag = (sender as FrameworkElement).Tag?.ToString();
if (!IsCoreWindow
&& WindowHelper.ActiveWindows.Values.FirstOrDefault()?.DispatcherQueue is DispatcherQueue dispatcherQueue
&& dispatcherQueue?.HasThreadAccess == false)
if (!IsCoreWindow && WindowHelper.ActiveWindows.Values.FirstOrDefault()?.DispatcherQueue is DispatcherQueue dispatcherQueue)
{
await dispatcherQueue.ResumeForegroundAsync();
}
Expand Down
3 changes: 1 addition & 2 deletions CoreAppUWP/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ namespace CoreAppUWP
{
public static partial class Program
{
private static HookRegistry hookRegistry;

private static unsafe bool IsPackagedApp
{
get
Expand Down Expand Up @@ -63,6 +61,7 @@ private static void Main()
ComWrappersSupport.InitializeComWrappers();
if (IsPackagedApp)
{
HookRegistry hookRegistry = null;
try
{
if (!IsSupportCoreWindow)
Expand Down
Loading

0 comments on commit 50e1549

Please sign in to comment.