Add synchronous thread extensions

This commit is contained in:
Michael Bucari-Tovo 2022-07-28 10:40:39 -06:00
parent aeaf234edd
commit 92327dcc0d
3 changed files with 51 additions and 10 deletions

View File

@ -0,0 +1,46 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Avalonia.Threading
{
internal static class AvaloniaThreadUtils
{
public static TResult Invoke<TResult>(this Dispatcher dispatcher, Func<TResult> function, DispatcherPriority dispatcherPriority = DispatcherPriority.Normal)
{
using var source = new CancellationTokenSource();
var task = dispatcher.InvokeAsync(function, dispatcherPriority);
task.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext());
dispatcher.MainLoop(source.Token);
return task.Result;
}
public static void Invoke(this Dispatcher dispatcher, Action action, DispatcherPriority dispatcherPriority = DispatcherPriority.Normal)
{
using var source = new CancellationTokenSource();
var task = dispatcher.InvokeAsync(action, dispatcherPriority);
task.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext());
Dispatcher.UIThread.MainLoop(source.Token);
}
public static T WaitOnUIAndGetResult<T>(this Task<T> task)
=> WaitOnDispatcherAndGetResult(task, Dispatcher.UIThread);
public static T WaitOnDispatcherAndGetResult<T>(this Task<T> task, Dispatcher dispatcher)
{
using var source = new CancellationTokenSource();
task.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext());
dispatcher.MainLoop(source.Token);
return task.Result;
}
public static void WaitOnUI(this Task task)
=> WaitOnDispatcher(task, Dispatcher.UIThread);
public static void WaitOnDispatcher(this Task task, Dispatcher dispatcher)
{
using var source = new CancellationTokenSource();
task.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext());
dispatcher.MainLoop(source.Token);
}
}
}

View File

@ -1,4 +1,5 @@
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Threading;
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -18,11 +19,7 @@ namespace LibationAvalonia
public static T ShowDialogSynchronously<T>(this Avalonia.Controls.Window window, Avalonia.Controls.Window owner) public static T ShowDialogSynchronously<T>(this Avalonia.Controls.Window window, Avalonia.Controls.Window owner)
{ {
using var source = new CancellationTokenSource(); return window.ShowDialog<T>(owner).WaitOnUIAndGetResult();
var dialogTask = window.ShowDialog<T>(owner);
dialogTask.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext());
Avalonia.Threading.Dispatcher.UIThread.MainLoop(source.Token);
return dialogTask.Result;
} }
} }
} }

View File

@ -10,6 +10,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
using Avalonia.Threading;
namespace LibationAvalonia namespace LibationAvalonia
{ {
@ -150,12 +151,9 @@ Libation.
private static DialogResult ShowCoreAsync(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, bool saveAndRestorePosition = true) private static DialogResult ShowCoreAsync(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, bool saveAndRestorePosition = true)
{ {
using var source = new CancellationTokenSource(); var dialogTask = Dispatcher.UIThread.Invoke(() => CreateMessageBox(owner, message, caption, buttons, icon, defaultButton, saveAndRestorePosition));
var dialogTask = Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => CreateMessageBox(owner, message, caption, buttons, icon, defaultButton, saveAndRestorePosition));
dialogTask.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext());
Avalonia.Threading.Dispatcher.UIThread.MainLoop(source.Token);
return DisplayWindow(dialogTask.Result, owner); return DisplayWindow(dialogTask, owner);
} }
private static MessageBoxWindow CreateMessageBox(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, bool saveAndRestorePosition = true) private static MessageBoxWindow CreateMessageBox(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton, bool saveAndRestorePosition = true)