none
WPF тормозит интерфейс. RRS feed

  • Вопрос

  • Проблема вот в чем. 
    Сразу при открытии программы все работает шустро.
    Программа запрашивает с сервера объемный список информации, после отображения которой в ListView, интерфейс программы начинает жестко тормозить на различных ивентах. Т.е. когда программа просто "стоит", процессор на нулях, а когда начинаешь например кликать мышкой по пустому месту на форме или открывать обычное меню, то процессор начинает жестко забиваться. Не смотря на то, что отрисовка списка и его листание идет очень даже хорошо. Тормозит все остальное.
    Через тулу Visual Profiler мне удалось узнать, что процессор занимает "Dispatcher Invoke". В программе диспетчер используется. но даже если его убрать, ничего не меняется в производительности. В чем еще может быть проблема? может кто сталкивался с подобной? очень нужна помощь. Заранее огромное спасибо.
    Через программку Snoop показало, что левых ивентов не генерируется. Теперь я вообще в замешательстве...
    • Перемещено Abolmasov Dmitry 6 февраля 2012 г. 10:49 (От:Языки программирования)
    27 января 2012 г. 13:00

Ответы

  • При имплементации команды вы могли сделать следующее:

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    

    Это добавляется для автоматической проверки CanExecute. Часто она излишня. Попробуйте её убрать, если она есть и оставьте только:

    public event EventHandler CanExecuteChanged;
    
    • Помечено в качестве ответа Abolmasov Dmitry 14 февраля 2012 г. 7:32
    2 февраля 2012 г. 8:36
    Отвечающий

Все ответы

  • > мне удалось узнать, что процессор занимает "Dispatcher Invoke".
     
     
    попробуйте заменить на Dispatcher.BeginInvoke

     

    • Изменено Malobukv 27 января 2012 г. 13:17
    27 января 2012 г. 13:16
  • но понимаешь, на клике мышкой он не вызывается. в чем тогда смысл замены?
    27 января 2012 г. 13:21
  • > на клике мышкой он не вызывается. в чем тогда смысл замены?


    в том, что Dispatcher.BeginInvoke выполняется асинхронно.
    потоки не ждут завершения вызова, как в случае с Dispatcher.Invoke (выполняется синхронно).
    в итоге UI не тормозит.
      
      

    27 января 2012 г. 13:38
  • вот смотри. передо мной открыта программа. Загрузка ЦП 0%. я начинаю ПРОСТО кликать на пустом месте формы и загрузка поднимается до 25%! причем никакие ивенты не срабатывают! мой код не выполняется!

    Perfemence Profiler попробовал. Он мне показал, что кушает процессор функция system.windows.Application.Run().

    27 января 2012 г. 13:41
  • Проблема скорее всего в том, что у вас не включена виртуализация. В листвью пропишите:

    VirtualizingStackPanel.IsVirtualizing="True"

    27 января 2012 г. 15:34
    Отвечающий
  • Виртуализация была включена. не решение.
    27 января 2012 г. 16:51
  • > Загрузка ЦП 0%. я начинаю ПРОСТО кликать на пустом месте формы и загрузка поднимается до 25%!


    следующий пример что выдает? у меня не более 3.

    using System;
    using System.Diagnostics;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Threading;
    
    namespace WpfApplication3
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                var lbl = new Label() { Content = "loading..." };
                this.Content = lbl;
                
                var p = Process.GetCurrentProcess();
                var cpu = new PerformanceCounter("Process", "% Processor Time", p.ProcessName, true);
                
                var count = 0;
                float sum = 0;
                new DispatcherTimer { Interval = TimeSpan.FromSeconds(1), IsEnabled = true }
                    .Tick += (s, e) =>
                        {
                            var v = cpu.NextValue();
                            sum += v;
                            lbl.Content = count++ + ": process CPU = " + v + "; " + (sum/count);
                        };
            }
        }
    }
    
    
    <Window x:Class="WpfApplication3.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Width="500" FontSize="16" Height="400" >
    </Window>
    
      

    27 января 2012 г. 23:34
  • также не более трех.
    28 января 2012 г. 10:29
  • Тогда нужен код.
    28 января 2012 г. 13:38
    Отвечающий
  • Здравствуйте.

    Посмотрите топик о повышении производительности ListView - WPF ListView Very Slow Performance - Why? (ElementHost, or Other Reason?). Попробуйте использовать предложенные там решения по виртуализации UI и виртуализации самих данных.

    Надеюсь это поможет вам в решении проблемы.


    Для связи [mail]
    29 января 2012 г. 23:23
  • понимаете, у меня виртуализация включена. да и в списке более чем 500 элементов не бывает, а интерфейс после загрузки этого ListView начинает тормозить, и не перестает после очистки этого списка
    30 января 2012 г. 6:11
  • Тогда как и сказал Антон, нужна разметка xaml и пример заполнения вами ListView.


    Для связи [mail]
    30 января 2012 г. 8:04
  • Есть определенные продвижения. 

    Тормоза из-за кнопок в каждом элементе ListView. 

     <Button 

                                            Command="{x:Static local:LibraryCommands.ChangedLockingLinePosition}" CommandParameter="{Binding}"

                                          >

                                        <Button.Content>

                                            <ad:GreyableImage Source="{Binding IsBlocked, Converter={StaticResource IsBlockedToImageConverter}, Mode=OneWay}"/>

                                        </Button.Content>

                                    </Button>

    Таких кнопок по три в каждом элементе. если убрать строку с командами в каждой такой кнопке, то никаких тормозов не наблюдается. я так понимаю это из-за RoutedUICommand, коотрыми и являются команды на кнопках. у этих команд также есть Execute и CanExecute. Какая может быть альтернатива RoutedUICommand?

    31 января 2012 г. 13:52
  • Напишите свою ICommand, или, если используете Prism, используйте DelegateCommand. Главное - не подписывайтесь в ней на события CommandManager-а, возможно как раз из-за этого все и тормозит.
    1 февраля 2012 г. 9:25
    Отвечающий
  • в смысле? из-за того, что я добавляю в CommandManager эти события? тормоза могут быть в этом?

    У меня как раз все через CommandManager регистрируется. Если регистрировать через альтернативу (Application.Current.MainWindow.CommandBindings.Add), сдвигов не дает в производительности.

    • Изменено graffinchik 2 февраля 2012 г. 7:20
    1 февраля 2012 г. 20:37
  • При имплементации команды вы могли сделать следующее:

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    

    Это добавляется для автоматической проверки CanExecute. Часто она излишня. Попробуйте её убрать, если она есть и оставьте только:

    public event EventHandler CanExecuteChanged;
    
    • Помечено в качестве ответа Abolmasov Dmitry 14 февраля 2012 г. 7:32
    2 февраля 2012 г. 8:36
    Отвечающий
  • нет, такого у меня нету...
    3 февраля 2012 г. 6:07
  • Это есть в RoutedCommand и как следствие в RoutedUICommand. Попробуйте эту команду заменить на свою.
    3 февраля 2012 г. 9:24
    Отвечающий