Formulário de animação opacidade em C # com um BackgroundWorker

votos
1

Com a ajuda do BackgroundWorker, eu criei uma animação de opacidade para alguma forma.

Há apenas um problema minúsculo com esta abordagem, mas eu não consigo entender onde está o problema. A velocidade da animação é configurável e até mesmo se o valor da velocidade é muito alta, às vezes as animações é muito, muito lento, por algum motivo estranho ...

A animação lenta Eu estou falando não é gaguejar, a animação é realmente muito bom, ele só leva mais tempo para executar toda a animação (de 0% a 100%, ou vice-versa). Isso só acontece de vez em quando. Parece (não tenho certeza) que acontece quando o computador está fazendo algum outro pouco intensivo, ação, fundo.

Preciso corrigir isso, claro, mas eu também gostaria de saber se há qualquer maneira que você iria melhorar este código ou se faria de forma diferente e / ou melhor.

Aqui está o meu código:

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();
}
Publicado 19/05/2009 em 16:59
fonte usuário
Em outras línguas...                            


2 respostas

votos
1

Cada vez que você alterar a opacidade do formulário, o Windows tem para redesenhar todas as janelas abaixo dele, a própria janela e, em seguida, aplicar opacidade (Vista faz isso muito mais rápido e tamponada). Desde que você está percorrendo cada estado opacidade a partir de 1 ... 100 este processo tem que completar 100 vezes. Às vezes redesenhar sua janela ou uma janela abaixo será lento.

O método Thread.Sleep com um valor> 0 vai dormir de 0 ... ~ 10ms não importa o valor que você passa. A resolução do temporizador fio Scheduler no Windows é de aproximadamente 10ms (Novamente, Vista e outra mudança OS e otimizar por isso não é exato) para que você não pode marcar uma fatia de tempo menor do que isso. 100x10ms + o tempo para realmente processar pode levar toda a 2 segundos para fade in / out.

A maneira de acelerá-lo é reduzir o número de re-chama. Em vez de pisar 1 para a opacidade, passo 5, 10, etc., que reduz o número total de re-extrai necessária e resultaria em uma forma de desvanecimento em vez 100ms.

Respondeu 19/05/2009 em 20:22
fonte usuário

votos
0

No geral, não vejo muita coisa que pudessem alterar, pelo menos à primeira vista. Se você está vendo alguns gargalos de desempenho que você pode tentar ter um olhar para Formigas Profiler ou uma ferramenta de análise de código semelhante para ver se você pode identificar todas as seções lentas.

Respondeu 19/05/2009 em 19:26
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more