Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Yield method to Dispatcher for async programming #14199

Open
YohDeadfall opened this issue Jan 14, 2024 · 2 comments · May be fixed by #14212
Open

Add Yield method to Dispatcher for async programming #14199

YohDeadfall opened this issue Jan 14, 2024 · 2 comments · May be fixed by #14212

Comments

@YohDeadfall
Copy link
Contributor

YohDeadfall commented Jan 14, 2024

Design

The proposal is about adding adding two methods to be used while writing async code for easy thread or priority switching when it's required:

public class Dispatcher
{
+    public static DispatcherPriorityAwaiter Yield() =>
+         new DispatcherPriority.Background);

+    public static DispatcherPriorityAwaiter Yield(DispatcherPriority priority)
+         new(priority);
}

Methods are made static since while the Dispatcher type isn't static, there's only one instance of it without exceptions.

public readonly struct DispatcherPriorityAwaiter : INotifyCompletion
{
    private readonly DispatcherPriority _priority;

    public DispatcherPriorityAwaiter(DispatcherPriority priority) => _priority = priority;

    public void GetResult() { }

    public bool IsCompleted => false;
    public void OnCompleted(Action continuation) => Dispatcher.UIThread.Post(continuation, _priority);
}

DispatcherPriorityAwaiter is a struct, so it can be inlined into a state machine generated by the compiler for the method where the awaiter is used.

Usage

async Task DoSomethingAsync()
{
    // Do something in background
    // ...

    // Here we go to UI
    await Dispatcher.Yield();

    // Now it's possible to interact with UI components
}

The same thing is already provided by WPF via the same named methods. So for newcomers it should take less code to change during migration.

Alternatives

An alternative solution is to use AwaitWithPriority, but it requires a task to be passed in which means more allocations and more code to be written.

@maxkatz6
Copy link
Member

Methods are made static since while the Dispatcher type isn't static, there's only one instance of it without exceptions.

That’s not true, we have exceptions - XPF ;)
And in general, we still want to keep a possibility to allow multiple dispatcher threads, at least for testing.

@YohDeadfall
Copy link
Contributor Author

Then should it be also more WPF compatible, so parameterless Yiled will use DispatcherPriority.Background?

@YohDeadfall YohDeadfall linked a pull request Jan 15, 2024 that will close this issue
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants