Too*_*eve 13

tl;dr:“最佳实践”是在某些 UI 对象上使用。在代码隐藏中。Dispatcher this.Dispatcher.Dispatch
如果只有一个窗口,MainThread.BeginInvokeOnMainThread则等效。行为上没有区别。可从任何地方调用。但如果您参考 MainThread,则待定如何编写单元测试。


更新:DispatcherQueue多窗口 Windows-ONLY 应用程序的替代方案,在不在代码隐藏中时选择正确的调度程序。(如果您只有一个窗口,MainThread那么当不在代码隐藏中时,会更简单。并且可以跨平台工作。)


马特莱博的解释。感谢 Ligun Shen-MSFT 将此链接作为对问题的评论。

...主线程是静态的,所以它基本上是正确的。让我解释。

当您有一个 UI 组件(BindableObject、Button、Page、Window)时,它知道它被分配给哪个线程。某些平台(例如 Windows 和 iOS)要求在 UI 线程上创建 UI 对象。否则它会抛出。并且,调度程序被初始化为该线程。

MainThread 没有 UI 线程的概念,因此选择第一个。在大多数情况下,这是正确的,因为大多数平台只有 1 个“主线程”。Windows 是一个例外,因为它支持单独线程上的窗口。...


来自微软高级技术人员Rob Caplan 的回答(谷歌Rob Caplan Microsoft了解有关他是谁的更多信息):

“InvokeOnMainThread 过于简单化了 - 并非所有应用程序都有主线程或单个 UI 线程。将 Dispatcher 与 UI 对象相关联(该对象又将与线程绑定)更通用,并且可以更好地支持多窗口应用程序。”

也就是说:访问Dispatcher某些 UI 对象比使用 MainThread“更通用”。


实质细节:

如果这是一个单窗口应用程序,并且您正在编写不是代码隐藏的代码(不是 UI 对象的一部分),那么Application.Current.Dispatcher就方便且安全。亦是如此MainThread.BeginInvokeOnMainThread。这两者的行为相同;在这种情况下使用哪个并不重要。但是,请考虑以下各个点,这些点Dispatcher稍微被视为“最佳实践”。

  • 模拟测试:制作模拟IDispatcher比替换MainThread静态类更容易。

更多细节:

  • 如果您处于代码隐藏状态(与某些 UI 对象关联的代码),请使用this.Dispatcher.... (您可以省略this.;我只是为了清楚起见添加了它。)

  • 如果您不在代码隐藏中,并且在单窗口应用程序中,Application.Current.DispatcherMainThread方法的行为相同。然而,Application.Current.Dispatcher是首选,因为它是一个IDispatcher对象。因此,它具有与上述“代码隐藏”情况相同的语法。如果您需要传递到不同的IDispatcher. 例如模拟测试。或者如果将来您的代码在多窗口应用程序中使用。

  • 请勿MainThread使用,也不要Application.Current.Dispatcher多窗口应用程序中使用。您必须在被触摸的窗口上获取 UI 对象。如果您在 UI 元素中编写代码,请使用this.Dispatcher. [this.是可选的;为清楚起见,已显示。] 或者将对该窗口的任何 UI 元素的引用传递给您的方法 ( someUIElement.Dispatcher)。

  • 这似乎是正确的,感谢您发布正确的答案。但后来我对微软糟糕的文档感到不满。他们的官方文档在这里 https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/appmodel/main-thread?view=net-maui-7.0 称为“在 .NET 上创建线程”,这是荒谬的MAUI UI 线程”是错误的。我对毛伊岛的文档和错误感到非常非常沮丧。我想将其添加到列表中。为什么官方文档没有提到正确的方法,而正确的方法只能在一些论坛帖子上找到?显然不是你的错,再次。 (2认同)