如何在使用Windows应用程序SDK的WinUI 3桌面应用中获取DispatcherQueue

12
在WPF中, 所有的控件都继承自DispatcherObject,获取Dispatcher非常容易。
如何在WinUI 3 Windows App SDK中获取DispatcherQueue并在ViewModel中使用它?
编辑我的实现方法,在mm8最受欢迎的答案上进行扩展。
在我的ViewModel中创建一个属性: public Microsoft.UI.Dispatching.DispatcherQueue TheDispatcher { get; set; } 然后在MainPage.xaml.cs的代码后台MainPage_Loaded事件中获取dispatcher ViewModel.TheDispatcher = this.DispatcherQueue; 现在我在VM中拥有了dispatcher,所以从VM中使用很容易:
TheDispatcher.TryEnqueue(() =>
{
     // some ui thread work
});

注意:我并没有把这个作为答案发布,因为已经有了一个答案。这是我的实现,旨在帮助任何对此感兴趣的人。
3个回答

25

在调度线程上调用 DispatcherQueue.GetForCurrentThread() API。

如果您在调度线程上创建视图模型,您可以在构造函数中或直接在初始化器中调用该方法,就像我在您的其他问题中演示的那样。

如果您在后台线程上创建视图模型,您将需要使用在实际调度线程上之前创建的DispatcherQueue对它们进行注入,例如:

DispatcherQueue dispatcherQueue = DispatcherQueue.GetForCurrentThread();

Task.Run(() => 
{
    ViewModel vm = new ViewModel(dispatcherQueue);
    ...
});

5
我无法为这个答案点赞足够多。我对在其他地方(比如 MS 文档)找到这样的指导有多么困难感到震惊,甚至连命名空间都没有正确更新。谢谢。来到这里的任何人都要仔细阅读这个答案。你必须在 UI 线程上调用 GetForCurrentThread(),然后在其他线程中引用它以供以后使用! - biomiker
在什么情况下我会使用DispatcherQueue.TryEnqueue(() => { 你的代码 });Task.Run(()=>{ 你的代码 });?假设我有一个包含1000个视图模型的循环,并且我在每个视图模型上调用. public async Task DoWork(),我可以通过循环遍历它们并只执行vm.DoWork();(不带await),或者使用dispatcherQueue.TryEnqueue(async () => { await vm.DoWork(); });。哪种方式更好?为什么?假设DoWork()执行一些耗时的工作,然后更新一个调用OnPropertyChanged()的属性。 - IronHide

4

是的,获取DispatcherQueue与WPF不同,在WinUI3中类似于以下内容:

var dispatcherQueue = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();

之后,您可以使用TryEnqueue方法。


3

我理解在使用WINUI-3时你的痛苦。 如果你在threadworkerPool中,且想要回到主线程,WINUI-3目前不支持使用Dispatcher。 可以尝试使用以下方法:

Microsoft.UI.Dispatching.DispatcherQueue.TryEnqueue(() => {
         Your code 
    });   

我在这方面浪费了很多时间,最终我得到了这个结果,希望这对您也有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接