Как реализован Invalidate ???
От: Cynic Россия  
Дата: 09.05.08 22:15
Оценка:
Писал тут код для реализации индикатора хода процесса. Индикатор поддерживает вращение вокруг оси. Для реализации вращения написал отдельный метод запускаемый конструктором класса в отдельном потоке. Назначение этого метода определённое количество раз в секунду вызывать метод Invalidate(). Выглядит этот метод примерно так:
    //...время последнего вызова Invalidate()...
    private long _lastInvalidateTick = 0;

    protected override void OnInvalidated(InvalidateEventArgs e)
    {
        base.OnInvalidated(e);
        _lastInvalidateTick = DateTime.Now.Ticks;
    }

    void ReDrawBar()
    {
        //...количество выполнений метода в секунду...
        int timesPerSecond = 50;

        while (_rotateThread.ThreadState == ThreadState.Running)
        {
            if (_lastInvalidateTick == 0)
            {
                Invalidate();
                continue;
            }

            //...время прошедшее после последнего вызова Invalidate()...
            float elapsedTime = (DateTime.Now.Ticks - _lastInvalidateTick) / 10000000f;

            if (elapsedTime > 1 / (timesPerSecond * 2f))
            {
                _currentRotateAngle += _rotateSpeed * elapsedTime;
                Invalidate();
            }
            Thread.Sleep(1000 / timesPerSecond);
        }
    }

Прокомментирую.
    if (elapsedTime > 1 / (timesPerSecond * 2f))

Эта условие не вызывает метод Invalidate() если он был вызван "недавно". То есть если метод выполняется 50 раз в секунду(каждые 0,02 секунды), а с момента последнего выполнения Invalidate() прошло времени меньше чем 0,02 секунды, то Invalidate() повторно не вызывается, т.к. в этом просто нет смысла, потому что индикатор и так был не давно перерисован.
И вроде все работает как надо, однако когда начал тестировать заметил одну особенность. Если метод вызывал Invalidate() 50 раз в секунду, то OnPaint() вызывался только 10-12 раз в секунду! Если количество вызовов метода увеличивалось до 100 раз в секунду ситуация не менялась, OnPaint() упорно вызывался с таким же промежутком. Это навело меня на мысль, что реализация Invalidate() специально вызывает OnPaint() не очень часто
Поэтому вопросы такие: Сколько раз в секунду вызывается OnPaint и, что этим управляет? Возможна ли ситуация, и когда, что OnPaint вызывается чаше чем в моем случае? Как повлиять на количество вызовов OnPaint за промежуток времени
:)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.