-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Feature/stateful dispatcherqueue extensions #4097
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
base: winui
Are you sure you want to change the base?
Feature/stateful dispatcherqueue extensions #4097
Conversation
Thanks Sergio0694 for opening a Pull Request! The reviewers will test the PR and highlight if there is any conflict or changes required. If the PR is approved we will proceed to merge the pull request 🙌 |
Any tests we can add? |
4b0be02
to
521082f
Compare
@michael-hawker Yup, I was thinking we might want to add some tests as well, and/or use these extensions somewhere in the sample app so that we can test them interactively as well. I also just wanted to get your thoughts and Alex's on this proposal too though, as in, whether having code like this is ok in the Toolkit. I understand there's some... Uh... Trickery involved ahah 😄 |
521082f
to
756dba9
Compare
Added a slight implementation change in 9e6431f after talking with @jakobbotsch (thanks again for the help!) to remove the type safety violation and ref type aliasing we were doing over the stored delegate in order to invoke it as contravariant in its inputs (which was in turn a workaround the lack of generic support for methods being invoked from native code due to the generic context). That addresses the potential issue with that trick that has been discussed with Jan and Levi here and here. This PR should be good for an initial review pass now (and as previously discussed with Michael, I'm also waiting for confirmation that we're fine with integrating code like this into the Toolkit in general, given its "unfriendliness"). The only other missing optimization left is to just swap those |
9e6431f
to
5c6534d
Compare
a14f7fc
to
6e5e721
Compare
Fixes microsoft/microsoft-ui-xaml#3321
PR Type
What kind of change does this PR introduce?
What is the current behavior?
The
DispatcherQueue.TryEnqueue
API does not have a stateful overload, meaning that (as I've mentioned here), the only way to pass some state to the callback is by using a C# closure. This is problematic from a performance standpoint, especially in cases where this method is invoked very often. Consider a classic example where we want to invoke some method on a control, from the UI thread:This will result in the following code:
That is, for each invocation we're allocating:
new <>c__DisplayClass1_0()
)new Action(<>c__DisplayClass1_.<Dispatch_WithCapture>b__0)
)What is the new behavior?
This PR solves all the issues mentioned above by adding the following new APIs:
These let developers explicitly pass a state which will be forwarded to the supplied delegate, so that the delegate itself can be stateless. This in turn lets the C# compiler statically cache it. In practice, we're no longer allocating closure classes, nor delegates, and not even interop wrappers at all, as we're doing everything manually here. Here's some benchmarks:
You can see how the new APIs are almost 7x faster than the built-in ones, and they're also completely allocation free 🚀
This might be especially useful for library authors writing controls and trying to reduce their own overhead on consumers.
PR Checklist
Please check if your PR fulfills the following requirements: