Писал тут код для реализации индикатора хода процесса. Индикатор поддерживает вращение вокруг оси. Для реализации вращения написал отдельный метод запускаемый конструктором класса в отдельном потоке. Назначение этого метода определённое количество раз в секунду вызывать метод 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 за промежуток времени