Проблемы с производительностью при создании простой анимации загрузки в WPF - PullRequest
1 голос
/ 16 декабря 2010

Я пытаюсь создать блестящий загрузчик в WPF. Предполагается, что в кругах есть круги, и он должен вращаться, давая пользователю что-то, на что можно посмотреть, пока я обрабатываю некоторые данные. Картинка прилагается. Вы можете заметить, что фактический результат несколько низкого качества. Это потому, что независимо от того, что я пытаюсь сделать, спиннер занимает около 5-7% процессорного времени. Это не приемлемо для меня, так как ... ну, это спиннер. Он вращается, когда компьютер занят чем-то, и я, честно говоря, хочу, чтобы он сделал это раньше, а не позже.

http://image.bayimg.com/babieaadh.jpg

Хорошо, поэтому код XAML определяет две вложенные сетки следующим образом:

<Grid 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WPFTest.Spinner"
    Name="View" Width="40" Height="40">
    <Grid Name="Grid" Width="40" Height="40" >
        <Grid.CacheMode>
            <BitmapCache EnableClearType="False" RenderAtScale="1" SnapsToDevicePixels="False"/>
        </Grid.CacheMode>
    </Grid>
</Grid>

Остальное в коде позади, в основном добавление нескольких эллипсов и настройка анимации.

Первый мой метод создания эллипсов:

    private static Ellipse GetEllipse(double x, double y, double opacity)
    {
        return new Ellipse
                   {
                       Fill = new SolidColorBrush(Colors.White),
                       Width = Size,
                       Height = Size,
                       Margin = new Thickness(x, y, 0, 0),
                       Opacity = opacity
                   };
}

Конструктор Spinner

   public Spinner()
    {
        InitializeComponent();

        const double step = 2 * Math.PI / Count; //Cound is const = 8
        const double r = 1.4 * Field; //Field is const = 40

        double angle = 0;
        for (var i = 0; i < Count; i++)
        {
            Grid.Children.Add(GetEllipse(r * Math.Cos(angle),  r * Math.Sin(angle), 1 - i/(double) Count));
            angle += step;
        }

        _doubleAnimation = new DoubleAnimation(0, 360, new Duration(new TimeSpan(0, 0, 1)))
                              {
                                  RepeatBehavior = RepeatBehavior.Forever,
                              };
        Grid.RenderTransform = new RotateTransform(0, Field, Field);
        RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.NearestNeighbor); //Low quality!
        Grid.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, _doubleAnimation );
    }

Теперь все это в основном работает, и это даже довольно мило, когда вы удаляете линии, которые устанавливают все на низкое качество. Но это в конечном итоге бесполезно. Если я загружаю что-то, и этот спиннер занимает 5-7% моего процессора, то это проблема для меня. Конечно, многоядерный ... что угодно. Нет, это должно работать! :)

Моя следующая лучшая идея исправить это - вместо вращения счетчика, просто сбросить цвет каждого отдельного эллипса через некоторый интервал. Я попробую это в конце концов, но между тем было бы очень интересно узнать, что происходит, и почему такая простая анимация длится вечно. Кроме того, если есть атрибут «MakeAnimationWorkBetter», который я не установил, я был бы очень обязан выяснить, где и как ...

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 16 декабря 2010

Вы можете уменьшить частоту кадров анимации с помощью вложенного свойства TimeLine.DesiredFrameRate:

<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:0.5" 
             From="1.0" To="0.5" Timeline.DesiredFrameRate="30" />

По умолчанию установлено значение 60fps.

С уважением, Колин Е.

1 голос
/ 16 декабря 2010

Вместо использования преобразования поворота, которое относительно дорого, почему бы не изменить непрозрачность эллипсов, что является гораздо более дешевым действием?

Гилад.

0 голосов
/ 17 апреля 2012

Посмотрите и на эту замечательную статью

http://www.abhisheksur.com/2011/03/deal-with-cpu-usage-in-wpf-applications.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...