Browse Source

Make Dispatcher.Yield use the current dispatcher (#20956)

pull/20549/merge
Julien Lebosquain 3 days ago
committed by GitHub
parent
commit
3068850405
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      src/Avalonia.Base/Threading/Dispatcher.Invoke.cs
  2. 75
      tests/Avalonia.Base.UnitTests/DispatcherTests.cs

5
src/Avalonia.Base/Threading/Dispatcher.Invoke.cs

@ -737,9 +737,6 @@ public partial class Dispatcher
/// </exception>
public static DispatcherPriorityAwaitable Yield(DispatcherPriority priority)
{
// TODO12: Update to use Dispatcher.CurrentDispatcher once multi-dispatcher support is merged
var current = UIThread;
current.VerifyAccess();
return UIThread.Resume(priority);
return CurrentDispatcher.Resume(priority);
}
}

75
tests/Avalonia.Base.UnitTests/DispatcherTests.cs

@ -512,76 +512,59 @@ public partial class DispatcherTests
[Fact]
public async Task DispatcherResumeContinuesOnUIThread()
public async Task DispatcherResumeContinuesOnCurrentThread()
{
using var services = new DispatcherServices(new SimpleControlledDispatcherImpl());
var tokenSource = new CancellationTokenSource();
var workload = Dispatcher.UIThread.InvokeAsync(
var dispatcher = Dispatcher.CurrentDispatcher;
var workload = dispatcher.InvokeAsync(
async () =>
{
Assert.True(Dispatcher.UIThread.CheckAccess());
Assert.True(dispatcher.CheckAccess());
await Task.Delay(1).ConfigureAwait(false);
Assert.False(Dispatcher.UIThread.CheckAccess());
Assert.False(dispatcher.CheckAccess());
await Dispatcher.UIThread.Resume();
Assert.True(Dispatcher.UIThread.CheckAccess());
await dispatcher.Resume();
Assert.True(dispatcher.CheckAccess());
tokenSource.Cancel();
});
Dispatcher.UIThread.MainLoop(tokenSource.Token);
dispatcher.MainLoop(tokenSource.Token);
}
[Fact]
public async Task DispatcherYieldContinuesOnUIThread()
public async Task DispatcherYieldContinuesOnCurrentThread()
{
using var services = new DispatcherServices(new SimpleControlledDispatcherImpl());
var tokenSource = new CancellationTokenSource();
var workload = Dispatcher.UIThread.InvokeAsync(
async () =>
{
Assert.True(Dispatcher.UIThread.CheckAccess());
await Dispatcher.Yield();
Assert.True(Dispatcher.UIThread.CheckAccess());
tokenSource.Cancel();
});
Dispatcher.UIThread.MainLoop(tokenSource.Token);
}
[Fact]
public async Task DispatcherYieldThrowsOnNonUIThread()
{
using var services = new DispatcherServices(new SimpleControlledDispatcherImpl());
var dispatcher = Dispatcher.CurrentDispatcher;
var tokenSource = new CancellationTokenSource();
var workload = Dispatcher.UIThread.InvokeAsync(
var workload = dispatcher.InvokeAsync(
async () =>
{
Assert.True(Dispatcher.UIThread.CheckAccess());
Assert.True(dispatcher.CheckAccess());
await Task.Delay(1).ConfigureAwait(false);
Assert.False(Dispatcher.UIThread.CheckAccess());
await Assert.ThrowsAsync<InvalidOperationException>(async () => await Dispatcher.Yield());
await Dispatcher.Yield();
Assert.True(dispatcher.CheckAccess());
tokenSource.Cancel();
});
Dispatcher.UIThread.MainLoop(tokenSource.Token);
dispatcher.MainLoop(tokenSource.Token);
}
[Fact]
public async Task AwaitWithPriorityRunsOnUIThread()
public async Task AwaitWithPriorityRunsOnCurrentThread()
{
static async Task<int> Workload()
static async Task<int> Workload(Dispatcher dispatcher)
{
await Task.Delay(1).ConfigureAwait(false);
Assert.False(Dispatcher.UIThread.CheckAccess());
Assert.False(dispatcher.CheckAccess());
return Thread.CurrentThread.ManagedThreadId;
}
@ -589,25 +572,27 @@ public partial class DispatcherTests
using var services = new DispatcherServices(new SimpleControlledDispatcherImpl());
var tokenSource = new CancellationTokenSource();
var workload = Dispatcher.UIThread.InvokeAsync(
var dispatcher = Dispatcher.CurrentDispatcher;
var workload = dispatcher.InvokeAsync(
async () =>
{
Assert.True(Dispatcher.UIThread.CheckAccess());
Task taskWithoutResult = Workload();
Assert.True(dispatcher.CheckAccess());
Task taskWithoutResult = Workload(dispatcher);
await Dispatcher.UIThread.AwaitWithPriority(taskWithoutResult, DispatcherPriority.Default);
await dispatcher.AwaitWithPriority(taskWithoutResult, DispatcherPriority.Default);
Assert.True(Dispatcher.UIThread.CheckAccess());
Task<int> taskWithResult = Workload();
Assert.True(dispatcher.CheckAccess());
Task<int> taskWithResult = Workload(dispatcher);
await Dispatcher.UIThread.AwaitWithPriority(taskWithResult, DispatcherPriority.Default);
await dispatcher.AwaitWithPriority(taskWithResult, DispatcherPriority.Default);
Assert.True(Dispatcher.UIThread.CheckAccess());
Assert.True(dispatcher.CheckAccess());
tokenSource.Cancel();
});
Dispatcher.UIThread.MainLoop(tokenSource.Token);
dispatcher.MainLoop(tokenSource.Token);
}
private class AsyncLocalTestClass

Loading…
Cancel
Save