TabItem 的异步首次加载的性能问题

发布于 2024-12-05 11:17:37 字数 594 浏览 1 评论 0原文

当我加载 TabItem 时(每个 TabItem 都绑定到一个 ViewModel,每个 ViewModel 都有一个 DataTemplate),我的应用程序存在性能问题。为了解决这个问题,我在 ViewModel 构造函数中使用异步加载:

public MyViewModel(MyObject entity)
    {
       // WpfContext it's my Dispatcher
       Task.Factory.StartNew(() => WpfContext.Invoke(() =>
                                   {
                                       //Initialisation
                                       LoadMyObject(entity);
                                   }));
    }

使用这个解决方案,第一次加载 TabItem 时,需要一些时间,而且看起来并不是真正的异步。对于其他负载,它工作得很好并且是异步的。我不知道到底为什么。有什么建议吗?

I have a performance problem with my application, when I load a TabItem (each TabItem is bound to a ViewModel, each ViewModel having a DataTemplate). To solve this problem, I use an asynchronous loading in ViewModel constructor :

public MyViewModel(MyObject entity)
    {
       // WpfContext it's my Dispatcher
       Task.Factory.StartNew(() => WpfContext.Invoke(() =>
                                   {
                                       //Initialisation
                                       LoadMyObject(entity);
                                   }));
    }

With this solution, the first time the TabItem is loaded, it takes some times and seems not really asynchronous. For the other loads, it works good and asynchronously. I don't know exactly why. Any suggestion ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

知你几分 2024-12-12 11:17:37

调度程序上的 Invoke 是对任务的后台线程和 UI 线程(一旦它决定实际运行代码)的阻塞调用。

有时它看起来是异步的,因为 UI 线程正忙于显示新选项卡,因此后台线程的 Invoke 会阻塞,直到 UI 线程有时间处理它。当看起来像是同步时,UI 线程在显示新选项卡之前正在处理 Invoke 调用。所以,最后,我认为你有竞争条件。

要解决此问题,您可能需要重构 LoadMyObject 方法,以便它可以在后台线程上运行,或者您可以使用 Dispatcher.BeginInvoke 方法并为其提供较低的优先级,以确保新选项卡的显示先于处理LoadMyObject 调用

Invoke on a Dispatcher is a blocking call for both the background thread of your Task and then also the UI thread (once it decides to actually run your code).

It seems asynchronous sometimes because the UI thread is busy showing the new Tab, and so the Invoke from the background thread is blocking until the UI thread has time to process it. When it seems like it is synchronous, the Invoke call is being processed by the UI thread before the new Tab is being displayed. So, in the end, I think you have a race condition.

To resolve this, you may need to refactor your LoadMyObject method so it can be run on the background thread, or you could use the Dispatcher.BeginInvoke method and provide it a lower priority to ensure the display of your new Tab precedes the processing of the LoadMyObject call

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文