Tutorial C# – Delegates e Eventos…
Olá a todos. Hoje vou-vos falar de Delegates e Eventos, o que são e para que servem. Esta é a aplicação que vos disponibilizo para testarem tudo o que aqui vamos falar.
Delegates, são apontadores para funções, ou seja, são funções que nos permitem invocar outras. Eventos, utilizam os delegates para fazer a ponte entre as mensagens da aplicação e as nossas funções.
Os delegates são classes, logo podem ser declarados dentro e foras de uma classe, vai depender do nível de visibilidade que queremos que eles tenham.
Os delegates instanciam-se como todas as classes só que os parâmetros são nomes de uma função. Neste caso estamos a instanciar o delegate testeDelegate que foi definido em cima para a variável "t" que está a apontar para a função de nome "metodo"
Os delegates podem ser chamados também de forma assincrona, ou seja, noutro thread (mais tarde falaremos de multiThreading) o que vai aumentar a performance porque a função é executada em background e caso o processo seja demorado não bloqueia a aplicação.
Usa-se do método BeginInvoke()
Este método leva como parâmetros os parâmetros do delegate uma instância da classe AsyncCallback se quisermos resposta quando o processo termina e também o valor que queremos que nos devolva o AssyncState.
Esta função de callback e utilizada para saber se o processo já terminou, visto não termos essa percepção porque o sistema não o está a executar no UI(User Interface).
- Multicast
Podemos chamar uma ou mais funções por ordem de adição. Para adicionar funções a um delegate utiliza-se o += para retirar é o -=.
Como se vê na figura vão ser executadas as duas funções e vão aparecer duas messageBox.
- Anonymous Delegates
A capacidade de não ser necessário criar um método para o delegate em vez disso é um bloco de código usado como parâmetro do delegate.
Assim evitamos como acontece nas imagens anteriores, de criar uma função para o delegate, escrevemos logo o bloco de código.
Nesta imagem vemos também as lambda expressions uma nova funcionalidade do C# 3.0.
- Eventos
As aplicações desenvolvidas em .NET são "message-based" o que significa que a aplicação comunica com o windows e com ela própria através de mensagens.
O Receiver ou Handler, é quem está á espera do evento(mensagem) - É aqui que os delegates entram em acção.
Sender , será responsável por gerar (Raise) o evento no caso de eventos do rato ou teclado o sender é o .NET runtime.
Nota: o sender não tem conhecimento para quem está a enviar a mensagem, logo utilizam-se os delegates
A assinatura de uma função que recebe o evento é sempre esta sem retorno e como parâmetros um objecto e uma classe derivada de EventArgs
Vamos criar o nosso evento:
Passo 1: declaramos um enveto e um delegate public delegate void NossoEventHandler(object sender, NossoEventArgs e); public event NossoEventHandler DisparaEvento;
Passo 2: Criamos a nossa classe derivada de EventArgs, neste caso só retorna uma string public class NossoEventArgs : EventArgs { public string _texto;
public NossoEventArgs(string texto) { _texto = texto; } }
Passo 3: Definimos o eventHandler (a função que vai receber o evento)
DisparaEvento += new NossoEventHandler(NossoEvento);
("DisparaEvento" é o nosso evento que recebe o delegate "NossoEventHandler" que aponta para a nossa função "NossoEvento") 🙂 simples não é?!
Passo 4: Definimos a nossa função que vai servir de Handler, como é um evento que chama a função tem de ter sempre a assinatura objecto e EventArgs.
public void NossoEvento(object sender, NossoEventArgs e) { //Fim do nosso evento com os nossos eventArgs MessageBox.Show(e._texto); }
Passo 5: Chamar o nosso evento DisparaEvento(this, new NossoEventArgs("Ola"));
(this é o objecto, a nossa classe derivada de EventArgs que leva uma string como parâmetro).
No final ao chamar este evento vamos estar a chamar a nossa função "NossoEvento" e mostramos uma messageBox com o texto "Ola" que passamos no EventArgs.
Bom chegamos ao fim de mais uma sessão, esta foi bem puxada mas quem perceber isto está safo no mundo da programação quem não percebeu tem de praticar e passado alguns dias faz isto com uma perna ás costas.
Obrigado a todos pelo vosso apoio e até para a semana.
PS: Para a semana voltará ao formato de video.
Download: Delegantes e Eventos [40.70KB]
Este artigo tem mais de um ano
Bom Tutorial.. confesso que havia uma ou 2 coisas que me passavam ao lado e agora fiquei mais iluminado.
continua o bom trabalho Henrique
muito bom o tutorial,
num futuro, até podem fazer tutoriais de outras linguagens
Sinceramente só vejo vantagem nos delegates quando queremos criar “macros” e correr várias funções encadeadas. Porque para correr uma, a menos que seja assíncrona (e mm assim há outras soluções), não vejo grande vantagem.
Quanto ao tuto, bom trabalho!
[ http://www.revolucaodigital.net ]
Uso as delegates para uma 2ª thread modificar labels na thread mãe que tem o GUI. Só mais tarde descobri que com as backgroundworkers também dava.
Bom tutorial Henrique 😉
@Nastase
Ficaste com a ideia errada de delegates. Os delegates não servem apenas para chamar uma função que já conheces, mas sim para encapsular apontadores para funções que conheces ou não(criados em runtime), dizeres isso é o mesmo que dizeres que todo o conceito das linguagens de programação está errada, principalmente C++ que usa e abusa de pointers. O que são delegates? São a versão melhorada dos antigos pointers, porque são typeSafe,Object Oriented e seguros, ou seja, todos os erros que existiam antigamente deixaram de existir.
Sem delegates não poderiam existir eventos, porque os eventos chamam funções que não conhecem, esta é a sua principal função.
E agora com os delegates anónimos (parece um grupo) 🙂 ainda estão melhores.
Altos papos…quem sabe opina, quem não, como eu, só olhar e aprender…valeu 😉
http://www.delaorden.wordpress.com
@Nastase,
Uso bastante da maneira que o filipe disse.. visto que os delegates sao a unica maneira de mexeres em controlos de outras threads.. em meu uso pessoal é essencialmente para MultiThreading. 😛
Bom tutorial. Mais algumas dicas não faz mal a ninguem.
b1bpt@fiambre.dsi.uminho.pt
@Henrique, @José
Obrigado pelo esclarecimento! Com certeza que irei olhar com um pouco mais de atenção a tudo isto. E os exemplos que citam são altamente interessantes 😉
[ http://www.revolucaodigital.net ]
Nas linguagens orientadas a objectos não existem funções mas sim métodos. Parabéns pelo tutorial.
mto bom
mas imagens, para a proxima, em formato png. por favor
Sou habitualmente leitor assíduo destes mini tutoriais e desta vez penso que a clareza ficou um pouco a desejar. Talvez uns exemplos de aplicação tivessem permitido apresentar melhor as ideias. De qualquer modo elogio a escolha do tema que levanta a curiosidade para o seu estudo.
Paco
Mal tenha tempo começo a cultivar-me com este tutorial 😀
Mais uma vez obrigado Henrique Graça Graça 😛
Boa noite
Costumo ler estes mini tutoriais e neste caso despertou-me mais interesse pois poderá estar relacionado com um problema que estou a ter numa aplicação que estou a desenvolver…
Alguém me sabe dizer como passo informação para vários url’s de uma só vez?
Muito bem.., sim senhor…
http://nocomments.pt.vu
@ Paco
Compreendo-te perfeitamente mas confesso que a matéria era muita e não tinha muito tempo, foi um pouco a abrir. Mas obrigado pelo comentário.
@ Joel
Não percebi a questão podes reformular?
basicamente o que eu pretendo é abrir 3 páginas de uma só vez (embora seja o mesmo destino, pretendo enviar diferente informação no url) e acho que tal não é possível com o simples Response.Redirect(“url”) pois termina o processamento da página e passa para a página indicada
@Henrique Graça
Eis, ainda n tive tempo de ler este tutorial, mas vou colocar uma duvida pode ser que saibas, estou a ter um memory leak num programa que fiz,ate onde deixei chegou aos 460 MB de ram :/ tou a usar backgroundworker para fazer multithreading, dentro do backgroundworker executo um ciclo com 34000 iteracoes, la dentro n crio novas threads, e de 100 em 100 inicializo td o k tenho em memoria e guardo em disco o k tinha, sabes onde pode tar o problema?
@Shogun
verifica se os objectos que utilizas têm o método Dispose(). Se tiverem é imprescindível que o utilizes. Nesses casos apenas reinicializar as variáveis não chega para que o garbage collector passe e limpe a memória. É necessário indicar explicitamente que aqueles recursos podem ser libertados.
[ http://www.revolucaodigital.net ]
Porque é que a minha resposta ao Shogun não foi publicada??
@Nastase
Pois tive a ver isso e n têm, o k eu tou a fazer é pegar num determinado site que usa querystrings nas quais passa um id k no meu caso e 1 a 34000, saco o site faco parse do site e saco a informacao k me interessa, n percebo e pk e k me acontece isto se eu faco iterativamente o parse de cada um dos sites e inclusive tenho um sleep para libertar uma beca do processador.vou deixar isto a correr e ver o k acontece,pode ser k amanha tenha explodido 😛
So para informacao:
O tal programa rebentou, out of memory, foi a excepcao k lancou, tenho msm k ver o k se esta a passar,a unica hipotese k vejo e ele estar a criar threads paralelas e abrir streams k n devia e depois n os fexa.
@ Shogun
Uma coisa que podes tentar é forçar o Garbage Collector tens como deves já saber dois metodos para isso o GC.Collect() que vai correr todos os finalizers num thread diferente, ou o GC.WaitForPendingFinalizers() este é sincrono e só tens resposta quando são todos terminados.
Uma outra coisa que podes fazer é remover todos os event handlers(-=) dos teus controlos que não necessitem disso, por alguma razão isso ocupa memória. Outra coisa certifica-te sempre se metes os objectos a null.
Um bom programa para controlar isso é o ANTS profiler podes sacar um trial.
Com este programa podes ver onde estão os problemas de memória da tua aplicação, basta dizer qual é o executável para monitorizar.
http://www.red-gate.com/Products/ants_profiler/index.htm
Espero que isto ajude e tenhas sucesso.
@shogun tens outra opçao excepcionalmente simples.. que é tudo o que declaras quando nao precisas no final da funçao fazer “= null”
no final de cada funçao limpa todos os objectos que sao locais igualando a null;
simples mas eficaz.
Sou iniciante e assim mesmo ficou bem claro para mim, Valeu está de Parabens
Henrique pá…Já mostraste isto ao Neves? lol! Abraço!
Obrigado pelo artigo; como principiante em C#, achei-o muito útil e informativo.
No entanto, tenho um reparo a fazer: deveria rever o seu Português. Tem muitos erros de sintaxe e frases mal construídas. É uma pena que a forma desvalorize o conteúdo. Fica a sugestão de melhoria.
Cumprimentos
Rui Dias
show de bola!!
Parabéns
é bem antigo esse tutorial e muito interessante,mas se autor puder me explicar como consigo fazer chamar um evento dentro de um outro evento ficaria muito grato!!! 🙂
Mt bom o artigo. Eu tbm estava meio perdido em relação à delegates e eventos. Ajudou bastante!
Mtooo bom tutorial
Vlw ae kra… Esta tentando setar o label de statusBar de um form aberto no inicio do sistema, la de dentro dos arquivos abertos e agora foi. Vlw
Teria como eu passar um delegate como argumento em um evento?
Muito bom, obrigado pelo compartilhamento.
ajudou muito na compreensão.