none
Ajuda com a ProgressBar, quero colocar uma Barra de Progresso na hora que tiver Sincronizando o Banco de Dados. RRS feed

  • Pergunta

  •  Tenho um Sistema que faz Sincronismo entre 2 Bancos. Tenho um Banco Local SQL Compact 3.5 SP1 e um Banco WEB SQL Server 2005, que funciona assim. Eu digito no Sistema e as informações vão para o Banco Local, quando eu mando Sincronizar ele vai para o Banco WEB. Ai se eu tiver fora de casa eu mando Sincronizar o programa e todas as informações são atualizadas no Banco. Isso funciona perfeitamente, eu uso esse artigo para fazer o sistema  http://www.linhadecodigo.com.br/Artigo.aspx?id=2241

     Mas agora vai o meu problema, o Sistema demora alguns segundos para Sincronizar os 2 Bancos e o cliente não sabe se o Sistema está Sincronizando ou travado até que ele termine. Ai quero colocar um ProgressBar, pode ser na Propriedade "marquee" só para a barra ficar se mechendo e quando terminar enche a Barra, mas o pior é quando eu clico no Botão para Sincronizar ele trava a Barra e ela tambem fica parada até terminar o Sincronismo.
    segunda-feira, 12 de outubro de 2009 20:34

Respostas

  • Rodolfo,

    Realmente existe um erro no meu código. O que acontece é que estou utilizando objetos do formulário em uma thread diferente da thread do formulário. O ideal nesse caso é utilizar o InvokeRequired.

    Segue o código abaixo:

    // Inicia o progresso
    private void StartProgress()
    {
        if (this.InvokeRequired)
            BeginInvoke( new MethodInvoker( delegate() { StartProgress(); } ) );
        else
        {
            progressBar1.Style = ProgressBarStyle.Marquee;
            progressBar1.MarqueeAnimationSpeed = 100;
            progressBar1.Value = 0;
        }
    }

    // Finaliza o progresso
    private void StopProgress()
    {
        if (this.InvokeRequired)
            BeginInvoke( new MethodInvoker( delegate() { StopProgress(); } ) );
        else
        {
            progressBar1.Style = ProgressBarStyle.Blocks;
            progressBar1.MarqueeAnimationSpeed = 0;
            progressBar1.Value = 0;
        }
    }

    private void SeuOutroMetodoSincronizar()
    {
        // Cria SyncAgent
        BancoLocalSyncAgent syncAgent = new BancoLocalSyncAgent();

        // Chama método Synchronize de forma assíncrona
        // usando anonymous delegates
        Func<SyncStatistics> async = new Func<SyncStatistics>(syncAgent.Synchronize);
        async.BeginInvoke( (r) => {

       
        // Aqui o método Synchronize terminou...
            SyncStatistics  syncStats = async.EndInvoke(r);

            // Modifica progress bar
            StopProgress();

        }, null);

        // Na linha abaixo o método Synchrronize ainda está executando
        // Modifica o estilo do progress bar para indicar que existe um processamento
        StartProgress();
    }

    Obs: Não testei.

    Att.

    Ari C. Raimundo
    • Marcado como Resposta _Rodolfo quinta-feira, 15 de outubro de 2009 22:56
    quinta-feira, 15 de outubro de 2009 20:51
    Moderador

Todas as Respostas

  • Rodolfo,

    O ideal é chamar o método Synchronize() de forma assíncrona. Segue abaixo um link com a mesma dúvida sua:

    Asyncronous Syncing
    http://social.microsoft.com/Forums/en-US/uklaunch2007ado.net/thread/aba12aa1-6183-419a-af7c-0446e004f6cb

    Att.

    Ari C. Raimundo
    terça-feira, 13 de outubro de 2009 03:24
    Moderador
  • Ainda não consegui fazer o Sincronismo Funcionar com a Barra de Progresso. Tem algumas coisas que não encontro de qual classe que é e por isso o Sistema não Compila.

    GetSyncAgent() HandleSyncCompleted CAppLogger.LogException(ex);this
    .HandleSyncError(ex);<br/>
    Esses são os que não consigo encontrar.

    private
     void
     Sync()<br/>
    {<br/>
    SyncAgent syncAgent = this .GetSyncAgent();<br/>
    try <br/>
    {<br/>
    SyncStatistics stats = syncAgent.Synchronize();<br/>
    this .HandleSyncCompleted(stats);<br/>
    }<br/>
    catch (Exception ex)<br/>
    {<br/>
    CAppLogger.LogException(ex);<br/>
    this .HandleSyncError(ex);<br/>
    }<br/>
    }<br/>
    quarta-feira, 14 de outubro de 2009 19:12
  • Rodolfo,

    Pode mostrar o código que você está utilizando para fazer o sincronismo? O link que eu te passei foi só um exemplo, na verdade a minha sugestão seria que você realizasse a chamada assíncrona do método Synchronize.

    Segue abaixo uma maneira de chamar um método assíncrono. A mesma abordagem pode ser utilizada em Windows Forms.

    // Classe usada como exemplo
    class Teste
    {
        // Esse método demora 20 segundos para ser executado e retorna um inteiro
        public int ExemploSynchronize()
        {
            Thread.Sleep(20000);
            return 1;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Cria um objeto da classe teste
            Teste t = new Teste();

            // Chama método ExemploSynchronize de forma assíncrona
            // usando anonymous delegates
            Func<int> async = new Func<int>(t.ExemploSynchronize);
            async.BeginInvoke( (r) => {

                // Aqui o método ExemploSynchronize terminou...
                int retorno = async.EndInvoke(r);
                Console.WriteLine("Retorno do método ExemploSynchronize: {0}", retorno);

            }, null);

            // Aqui você faz o que quiser enquanto o método ExemploSynchronize
            // está sendo executado
            Console.WriteLine("Estou executando essa linha de código e o método ExemploSynchronize ainda está sendo executado...");

            Console.ReadKey();
        }
    }


    Att.

    Ari C. Raimundo
    quarta-feira, 14 de outubro de 2009 19:43
    Moderador
  • Pelo que eu vi no Exemplo, você para o Sistema por 20 Segundos. Isso pra mim não funciona,porque o Sincronismo varia muito. Quando ele não tem o que Sincronizar demora 1 segundo para avisar que está pronto. Mas quando ele tem vários Registros pode demorar até mais de 20 segundos. Agora vou testar a Segunda Classe que você me passou. A classe Program, se ele realmente pegar o Valor do Sincronismo e deixar fazer o que quiser, enquanto isso. Ai vou poder colocar a Barra, agora em relação ao Código é meio difícil de explicar. Pois eu uso a ferramenta de Sincronismo da Microsoft, que está nesse artigo e ela cria todo o Sincronismo. Eu só tenho que me preocupar em chamar o Método para o Sincronismo assim:

     

    BancoLocalSyncAgent syncAgent = new BancoLocalSyncAgent ();

    Microsoft.Synchronization.Data. SyncStatistics syncStats = syncAgent.Synchronize();

     

    Vou criar um exemplo de Sincronismo mais Simples e mando o Código Fonte Completo, daí explico aonde está o problema. Acho que fica mais fácil de entender.

    quinta-feira, 15 de outubro de 2009 12:10
  • Rodolfo,

    Não tem nada a ver o meu método parar por 20 segundos. Eu somente demonstrei um exemplo de um método que demora para executar.

    Minha sugestão é que você faça algo semelhante ao código abaixo:

    // Cria SyncAgent
    BancoLocalSyncAgent syncAgent = new BancoLocalSyncAgent();

    // Chama método Synchronize de forma assíncrona
    // usando anonymous delegates
    Func<SyncStatistics> async = new Func<SyncStatistics>(syncAgent.Synchronize);
    async.BeginInvoke( (r) => {

        // Aqui o método Synchronize terminou...
        SyncStatistics  syncStats = async.EndInvoke(r);

        // Modifica o estilo do progress bar para indicar que o processamento foi finalizado
        seuProgressBar.Style = ProgressBarStyle.Blocks;
        seuProgressBar.MarqueeAnimationSpeed = 0;
        seuProgressBar.Value = 0;

    }, null);


    // Na linha abaixo o método Synchrronize ainda está executando
    // Modifica o estilo do progress bar para indicar que existe um processamento
    seuProgressBar.Style = ProgressBarStyle.Marquee;
    seuProgressBar.MarqueeAnimationSpeed = 100;

    seuProgressBar.Value = 0;

    É possível utilizar o código também sem anonymous delegates. Depende da sua aplicação.

    Att.

    Ari C. Raimundo
    quinta-feira, 15 de outubro de 2009 14:12
    Moderador
  • É exatamente isso que eu preciso, mas esta dando um problema e só se estiver fácil. Se puder colocar uma ProgressBar do tipo Block que controle o Sincronismo pra mim é melhor, senão a ProgressBar como Marquee também resolve. O erro Acontece na Linha progressBar1.Style = ProgressBarStyle.Blocks;

    Esse é o Erro "Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on."


    // Cria SyncAgent
                BancoLocalSyncAgent syncAgent = new BancoLocalSyncAgent();

                // Chama método Synchronize de forma assíncrona
                // usando anonymous delegates
                Func<Microsoft.Synchronization.Data.SyncStatistics> async = new Func<Microsoft.Synchronization.Data.SyncStatistics>(syncAgent.Synchronize);
                async.BeginInvoke((r) =>
                {

                    // Aqui o método Synchronize terminou...
                    Microsoft.Synchronization.Data.SyncStatistics syncStats = async.EndInvoke(r);

                    // Modifica o estilo do progress bar para indicar que o processamento foi finalizado
                    progressBar1.Style = ProgressBarStyle.Blocks;
                    progressBar1.MarqueeAnimationSpeed = 0;
                    progressBar1.Value = 0;

                }, null);

                // Na linha abaixo o método Synchrronize ainda está executando
                // Modifica o estilo do progress bar para indicar que existe um processamento
                progressBar1.Style = ProgressBarStyle.Marquee;
                progressBar1.MarqueeAnimationSpeed = 100;
                progressBar1.Value = 0;
    quinta-feira, 15 de outubro de 2009 16:07
  • Rodolfo,

    Realmente existe um erro no meu código. O que acontece é que estou utilizando objetos do formulário em uma thread diferente da thread do formulário. O ideal nesse caso é utilizar o InvokeRequired.

    Segue o código abaixo:

    // Inicia o progresso
    private void StartProgress()
    {
        if (this.InvokeRequired)
            BeginInvoke( new MethodInvoker( delegate() { StartProgress(); } ) );
        else
        {
            progressBar1.Style = ProgressBarStyle.Marquee;
            progressBar1.MarqueeAnimationSpeed = 100;
            progressBar1.Value = 0;
        }
    }

    // Finaliza o progresso
    private void StopProgress()
    {
        if (this.InvokeRequired)
            BeginInvoke( new MethodInvoker( delegate() { StopProgress(); } ) );
        else
        {
            progressBar1.Style = ProgressBarStyle.Blocks;
            progressBar1.MarqueeAnimationSpeed = 0;
            progressBar1.Value = 0;
        }
    }

    private void SeuOutroMetodoSincronizar()
    {
        // Cria SyncAgent
        BancoLocalSyncAgent syncAgent = new BancoLocalSyncAgent();

        // Chama método Synchronize de forma assíncrona
        // usando anonymous delegates
        Func<SyncStatistics> async = new Func<SyncStatistics>(syncAgent.Synchronize);
        async.BeginInvoke( (r) => {

       
        // Aqui o método Synchronize terminou...
            SyncStatistics  syncStats = async.EndInvoke(r);

            // Modifica progress bar
            StopProgress();

        }, null);

        // Na linha abaixo o método Synchrronize ainda está executando
        // Modifica o estilo do progress bar para indicar que existe um processamento
        StartProgress();
    }

    Obs: Não testei.

    Att.

    Ari C. Raimundo
    • Marcado como Resposta _Rodolfo quinta-feira, 15 de outubro de 2009 22:56
    quinta-feira, 15 de outubro de 2009 20:51
    Moderador
  • Resolveu o meu Problema, nossa Cara muito Obrigado. Você resolveu um grande Problema meu, agora a Importação vai ficar muito Melhor. Muito Obrigado. Fiz o Código que você descreveu e só Chavei os 3 Métodos na Classe. Muito Obrigado
    quinta-feira, 15 de outubro de 2009 22:55
  • using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Microsoft.Synchronization.Data;

    namespace ApostilaWin
    {
        public partial class frmAtualizar : Form
        {
            public frmAtualizar()
            {
                InitializeComponent();
            }

            private void frmAtualizar_Load(object sender, EventArgs e)
            {
                SeuOutroMetodoSincronizar();
            }

            // Inicia o progresso
            private void StartProgress()
            {
                if (this.InvokeRequired)
                    BeginInvoke(new MethodInvoker(delegate() { StartProgress(); }));
                else
                {
                    prgAtualizar.Style = ProgressBarStyle.Marquee;
                    prgAtualizar.MarqueeAnimationSpeed = 100;
                    prgAtualizar.Value = 0;
                }
            }

            // Finaliza o progresso
            private void StopProgress()
            {
                if (this.InvokeRequired)
                    BeginInvoke(new MethodInvoker(delegate() { StopProgress(); }));
                else
                {
                    prgAtualizar.Style = ProgressBarStyle.Blocks;
                    prgAtualizar.MarqueeAnimationSpeed = 0;
                    prgAtualizar.Value = 100;
                }
            }

            private void SeuOutroMetodoSincronizar()
            {
                // Cria SyncAgent
                BancoLocalSyncAgent syncAgent = new BancoLocalSyncAgent();

                // Chama método Synchronize de forma assíncrona
                // usando anonymous delegates
                Func<SyncStatistics> async = new Func<SyncStatistics>(syncAgent.Synchronize);
                async.BeginInvoke((r) =>
                {

                    // Aqui o método Synchronize terminou...
                    SyncStatistics syncStats = async.EndInvoke(r);

                    // Modifica progress bar
                    StopProgress();

                }, null);

                // Na linha abaixo o método Synchrronize ainda está executando
                // Modifica o estilo do progress bar para indicar que existe um processamento
                StartProgress();
            }

        }
    }

    domingo, 6 de dezembro de 2009 14:49