Archive for August 2010

EFProfiler– Entity Framework Profiler

Se você está trabalhando com EF4, provavelmente já se perguntou se os comandos SQL gerados estão realmente otimizados, ou talvez quando você tem algum problema de performance. Para responder a isto existem várias ferramentas de análise, ou profilers, e um destes é o EFProfiler.

A ferramenta é bastante simples, você baixa um executável do site www.efprof.com e segue as instruções contidas no arquivo “How to use.txt”.

Para o profiler funciona, você precisa adicionar a referência de um DLL do Profiler ao seu projeto:

image

Depois, no arquivo principal do projeto, você executa o inicializador do profiler:

   1: static void Main(string[] args)

   2: {

   3:     // Profiler

   4:     HibernatingRhinos.Profiler.Appender.EntityFramework.EntityFrameworkProfiler.Initialize();

   5:  

   6:     TesteEntities dc = new TesteEntities();

   7:  

   8:     var dados = from c in dc.Cliente

   9:                 select c;

  10:     foreach (var linha in dados)

  11:     {

  12:         Console.WriteLine(linha.Nome);

  13:     }

  14: }

No exemplo acima, temos uma simples consulta ao banco de dados.

Agora abra o profiler e execute sua aplicação, os resultados irão aparecer na tela:

image

É isto aí pessoal, bom profiler para vocês!

[]s,

Carlos dos Santos.

Windows Forms – atualizando o formulário de dentro de uma Thread

É relativamente comum termos uma aplicação que precise usar uma ou mais threads para realizar algum processo demorado onde o usuário não precise ficar esperando, mas às vezes é necessário também que esta thread faça algum tipo de interação com a tela, talvez atualizando alguma informação, barra de progresso, enfim, mostrar ao usuário que algo está acontecendo.

Uma tarefa relativamente simples, mas que pode causar um certo transtorno justamente por ser uma thread. Veja a aplicação abaixo em Windows Forms:

image

É uma tela bem simples, com um botão e uma barra de progresso. Agora vamos imaginar que este form tenha o código abaixo, que cria uma thread que atualiza a progressBar1:

   1: public partial class Form1 : Form

   2: {

   3:     private bool threadAtiva = false;

   4:  

   5:     public Form1()

   6:     {

   7:         InitializeComponent();

   8:     }

   9:  

  10:     private void btnIniciar_Click(object sender, EventArgs e)

  11:     {

  12:         

  13:         Thread processo = new Thread(new ThreadStart(ExecutaThread));

  14:         processo.Start();

  15:  

  16:         progressBar1.Maximum = 100;

  17:         progressBar1.Value = 0;

  18:  

  19:         threadAtiva = true;

  20:     }

  21:  

  22:     void ExecutaThread()

  23:     {

  24:         while (threadAtiva)

  25:         {

  26:             if (progressBar1.Value > 99)

  27:             {

  28:                 threadAtiva = false;

  29:                 return;

  30:             }

  31:             progressBar1.Value++;

  32:             progressBar1.Refresh();

  33:         }

  34:     }

  35: }


O código acima está correto, mas ao executar e clicar no botão iniciar, aparece o seguinte erro:

image

O erro acontece porquê a janela da aplicacação (UI) está executando em uma thread e agora nós temos outra thread executando o nosso processo e tentando atualizar a tela. Então como resolver isto ?

Simplesmente usando um Invoker:

   1: void ExecutaThread()

   2:        {

   3:            while (threadAtiva)

   4:            {

   5:                if (progressBar1.Value > 99)

   6:                {

   7:                    threadAtiva = false;

   8:                    return;

   9:                }

  10:                this.Invoke(new MethodInvoker(delegate()

  11:                {

  12:                    progressBar1.Value++;

  13:                    progressBar1.Refresh();

  14:                }));

  15:            }

  16:        }

Agora estamos atualizando a tela ou seja, o progressBar1 usando um Invoker que está sendo executando sob a thread principal, ou seja, o formulário. Neste exemplo eu usei o MethodInvoker() com um método anônimo, mas você poderia ter criado um método e chamado sem problemas e com isto você pode ter várias thread rodando e atualizando a interface do usuário.

É isto aí pessoal, espero que dica seja útil para vocês.

Um abraço e até a próxima.

Carlos dos Santos.