2009-05-19 4 views
1

С помощью BackgroundWorker я создал анимацию непрозрачности для некоторой формы.Форма непрозрачности анимации в C# с BackgroundWorker

Существует только одна небольшая проблема с этим подходом, но я не могу понять, где проблема. Скорость анимации настраивается и даже если значение скорости очень велико, иногда анимация очень и очень медленно, по какой-то нечетной причине ...

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

Мне нужно исправить это, конечно, но я также хотел бы знать, есть ли способ улучшить этот код, или если вы сделаете это по-другому и/или лучше.

Вот мой код:

private const int TOGGLE_EFFECT_SPEED = 10; 

private void blendWorker_DoWork(object sender, DoWorkEventArgs e) { 
    bool blendIn = (bool)e.Argument; 

    // Loop through all opacity values 
    for(double value = 1; value <= 100; value += 1) { 
     // Report the current progress on the worker 
     blendWorker.ReportProgress(0, blendIn ? value : 100 - value); 

     // Suspends the current thread by the specified blend speed 
     System.Threading.Thread.Sleep(11 - TOGGLE_EFFECT_SPEED); 
    } 

    // Set the worker result as the inverse tag value 
    e.Result = !blendIn; 
} 

private void blendWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { 
    double opValue = (double)e.UserState; 

    // Show and repaint the whole main notes window? 
    if(opValue == 1.0) { 
     Show(); 
     Invalidate(true); 
    } 

    // Set the main notes window opacity value 
    Opacity = (double)e.UserState/100; 
} 

private void blendWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
    bool tagFlag = (bool)e.Result; 

    // Hide the main notes window? 
    if(tagFlag) { 
     Hide(); 
    } 

    // Set the main notes window tag value 
    Tag = tagFlag; 
} 

/* 
    THE FOLLOWING METHOD IS PART OF A DIFFERENT CLASS. 
    ACTUALLY, IT'S THE "PROGRAM" CLASS WHERE MAIN() 
    IS LOCATED. THIS METHOD IS CALLED TO SHOW/HIDE 
    THE MAIN APPLICATION FORM WITH AN OPACITY ANIMATION 
*/ 
internal static void ToggleNotesWindow() { 
    // Get the tag value converted to boolean type 
    bool tagFlag = Convert.ToBoolean(NotesWindow.Tag, CultureInfo.InvariantCulture); 

    // Bring the main notes window to front? 
    if(tagFlag) Program.NotesWindow.BringToFront(); 

    // Run the blend effect if it's not already running 
    if(!NotesWindow.blendWorker.IsBusy) { 
     NotesWindow.blendWorker.RunWorkerAsync(tagFlag); 
    } 

    // Activate and focus the main notes window? 
    if(tagFlag) Program.NotesWindow.Activate(); 
} 

ответ

1

Каждый раз, когда вы изменяете непрозрачность формы, Windows должна перерисовать все окна под ним, само окно, а затем применить непрозрачность (Vista делает это намного быстрее и буферизуется). Поскольку вы переходите через каждое состояние непрозрачности от 1 ... 100, этот процесс должен выполняться 100 раз. Иногда перерисовывание окна или окна под ним будет медленным.

Метод Thread.Sleep со значением> 0 будет спадать от 0 ... ~ 10ms независимо от того, какое значение вы передадите. Разрешение таймера планировщика потока в Windows составляет около 10 мс (Опять же, Vista и другие ОС меняются и оптимизируются, поэтому не являются точными), поэтому вы не можете планировать меньше времени. 100x10ms + время фактического рендеринга может занять 2 целых секунды, чтобы затухать.

Способ ускорить это, чтобы уменьшить количество повторных розыгрышей. Вместо того, чтобы набирать +1 для непрозрачности, шаг +5, +10 и т. Д. Это уменьшает общее количество требуемых повторных розыгрышей и приведет к замиранию формы за 100 мс.

+0

Я не думаю, что это правильно, я определенно вижу разницу в скорости затухания между TOGGLE_EFFECT_SPEED = 1 (sleep (10)) и TOGGLE_EFFECT_SPEED = 10 (sleep (1))). И я также вижу разницу между этими двумя значениями от 1 до 10. И я не думаю, что вы получили то, что я имел в виду под «медленным», потому что значение скорости не имеет значения, проблема, которую я испытываю, происходит без скорости изменение стоимости. –

+0

Вы не увидите большой разницы между значениями скорости от 1 до 10, поскольку планировщик потоков не спящий менее 10 мс в большинстве случаев, поэтому они будут иметь одинаковую скорость. Вещь, которая будет иметь самый большой эффект, - это то, как медленно это нужно, чтобы сделать ваше окно и окна под ним. –

0

В целом я не вижу много, что гарантировало бы изменение, по крайней мере на первый взгляд. Если вы видите некоторые узкие места производительности, вы можете попробовать взглянуть на Ants Profiler или аналогичный инструмент профилирования кода, чтобы узнать, можете ли вы точно определить любые медленные разделы.

+0

Но в то же время нет «медленных секций», код работает, он делает именно то, что должен делать. В некоторых других случаях, не так часто, он исчезает в замедленном темпе ... –

Смежные вопросы