microsoft / microsoft/WindowsAppSDK
Proposal: Add WinRT APIs to create Windows.System.DispatcherQueueController on current thread easily
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 4.7k
- Forks
- 471
- Avg merge
- 3d 13h
- Merged PRs (30d)
- 28
Description
I know there is a feature portal for proposal but this is very code-oriented/developer-experience related, so I wrote it here instead of the portal.
## Summary
Now that WinUI 3 mica support is here in 1.1 preview 3, each app that implement mica need to have their own dispatcher queue helper as in the [xaml control gallery](https://github.com/microsoft/WinUI-Gallery/blob/winui3/XamlControlsGallery/ControlPagesSampleCode/SystemBackdrops/SystemBackdropsEnsureSystemDQC.txt#L3), or in this [sample for C++](https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/system-backdrop-controller).
The ergonomic is not good in C# (dllimport), nor in C++ (using `ABI` namespace and C API directly for a release-defining feature).
This proposal suggests WASDK provide the following WinRT API:
```
namespace Microsoft.Windows.System
{
runtimeclass DispatcherQueueController
{
// Note the return type is WS instead of Microsoft.UI.Dispatching
static Windows.System.DispatcherQueueController CreateOnCurrentThread();
}
}
```
So C# and C++ can all use the same API. In the future this would benefit other supported language projection as well.
On top of that, I'm guessing the existing `Windows::System::DispatcherQueueController::CreateOnDedicatedThread` is just wrapping the ABI interface and C API anyways. To make the API in WinRT complete, this proposal suggests that a complete WinRT API that wraps `IDispatcherQueueController`, `DispatcherQueueOptions`, and `CreateDispatcherQueueController`, as follows:
```
namespace Microsoft::Windows::System
{
enum DispatcherQueueOptions
{
/*Map to existing DispatcherQueueOptions*/
}
runtimeclass DispatcherQueueController
{
static Windows.System.DispatcherQueueController CreateDispatcherQueueController(DispatcherQueueOptions options);
}
}
```
This has the following benefits:
- Improved developer experience
- Remove boilerplate in both languages
- Remove unnecessary errors/efforts on implementing mica
- API consistency (one for dedicated thread, one for current thread)
- Simplify doc effort on mica (I already [submitted a PR](https://github.com/MicrosoftDocs/windows-uwp/pull/3811) fixing C++'s sample code related to dispatcher queue controller)
## Examples Of Proposed API In The Mica Sample
### C++
```diff
winrt::WS::DispatcherQueueController CreateSystemDispatcherQueueController()
{
- DispatcherQueueOptions options
- {
- sizeof(DispatcherQueueOptions),
- DQTYPE_THREAD_CURRENT,
- DQTAT_COM_NONE
- };
-
- ::ABI::Windows::System::IDispatcherQueueController* ptr{ nullptr };
- winrt::check_hresult(CreateDispatcherQueueController(options, &ptr));
- return { ptr, take_ownership_from_abi };
+ return Microsoft::Windows::System::DispatcherQueueController::CreateOnCurrentThread();
}
```
### C#
```diff
class WindowsSystemDispatcherQueueHelper
{
- [StructLayout(LayoutKind.Sequential)]
- struct DispatcherQueueOptions
- {
- internal int dwSize;
- internal int threadType;
- internal int apartmentType;
- }
-
- [DllImport("CoreMessaging.dll")]
- private static extern int CreateDispatcherQueueController([In] DispatcherQueueOptions options, [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object dispatcherQueueController);
-
object m_dispatcherQueueController = null;
public void EnsureWindowsSystemDispatcherQueueController()
{
if (Windows.System.DispatcherQueue.GetForCurrentThread() != null)
{
// one already exists, so we'll just use it.
return;
}
- if (m_dispatcherQueueController == null)
- {
- DispatcherQueueOptions options;
- options.dwSize = Marshal.SizeOf(typeof(DispatcherQueueOptions));
- options.threadType = 2; // DQTYPE_THREAD_CURRENT
- options.apartmentType = 2; // DQTAT_COM_STA
-
- CreateDispatcherQueueController(options, ref m_dispatcherQueueController);
- }
+ m_dispatcherQueueController = Microsoft.Windows.System.DispatcherQueueController.CreateOnCurrentThread();
}
}
```
## Scope
| Capability | Priority |
| :---------- | :------- |
| This proposal will allow supported languages to use (the same) WinRT API to create `Windows::System::DispatcherQueueController` on current thread in 1 line | Must |
| This proposal will allow supported languages to use WinRT API to create `Windows::System::DispatcherQueueController` with options | Must |
## Notes
1. IMO this should be implemented by 1.1. So when this feature is officially rolled out no one has to write `dllimport`/`::ABI::` just to use mica.
2. Note that [the "existing" one in WinUI 3](https://docs.microsoft.com/en-us/windows/winui/api/microsoft.ui.dispatching.dispatcherqueuecontroller.createoncurrentthread?view=winui-3.0#microsoft-ui-dispatching-dispatcherqueuecontroller-createoncurrentthread) doesn't work as it creates `MUD` instead of `WS` dispatcher queue controller.
3. I'd love to submit a PR for this but I need to make sure the proposal is accepted before investing my time on it.
## Potential Confusion
Developers might be confused about the difference between `Windows::System::DispatcherQueueController`, `Microsoft::Windows::System::DispatcherQueueController` (proposed, only contain static method to create `WS::DispatcherQueueController`), and `Microsoft::UI::Dispatching::DispatcherQueueController`, and which to use. We might need to provide a doc that explains them briefly. The doc might need to explain
- Should use MUDD mostly in WinUI 3
- WSD is the type for e.g. using mica
- MWSD is for convenience method
## Open question
Since the proposed class only contains static methods, is it more appropriate to name it `DispatcherQueueControllerHelper`?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.