Miguel Ferreira
miguel.ferreira@dotnetraptors.com.br
www.southern.com.br
- Como posso fazer para saber se uma thread do threadpool concluiu sua tarefa?
Até onde eu sei, não há como fazer isto usando o ThreadPool diretamente. Podemos, no entanto, utlizar o padrão de chamadas assíncronas para garantirmos que um método de callback será executado.
Digamos que pretendemos executar o seguinte método em uma Thread do ThreadPool e sermos notificados de sua conclusão:
class Classe {
...
void Metodo(int param);
...
}
Primeiro criamos um objeto delegate para este método:
delegate void MetodoDelegate(int param);
Classe oClasse = new Classe();
MetodoDelegate meuDel = new MetodoDelegate(oClasse.Metodo);
Chamamos o delegate assíncronamente passando um AsyncCallback delegate representando o método que será executado/chamado ao final da execução do delegate.
// Repare no método: BeginInvoke
meuDel.BeginInvoke(100, new AsyncCallback(MeuCallback), meuDel);
O método Metodo será executado em uma thread do ThreadPool e assim que este concluir, o método MeuCallback será chamado. Observe que o último parâmetro do BeginInvoke é chamado AsyncState. Por meio dele podemos passar qualquer objeto para o método MeuCallback. Usualmente passamos o próprio objeto delegate de forma a podermos chamar o método EndInvoke do mesmo. Repare na declaração do delegate AsyncCallback:
public delegate void AsyncCallback(IAsyncResult ar);
Para obtermos o objeto AsyncState de dentro do método de callback (MeuCallback), basta ler a propriedade IAsyncResult.AsyncState.
--
Estive lecionando em um treinamento interno no SERPRO, especificamente sobre delegates, e um dos colegas presentes me fez uma pergunta, no mínimo curiosa, enquanto eu estava expondo o tópico de eventos:
- Qual a diferença entre delegates e eventos?
Pergunta interessante!!!! Eu dei uma engasgada pois nunca me fiz esta pergunta uma vez que o sistema de eventos do .NET é baseado em delegates, e, portanto, não tinha a resposta pronta. Minha percepção (e resposta) é a seguinte:
Eventos são modificadores dos delegates - veja a declaração no código abaixo;
Podemos incluir eventos nas interfaces, mas não delegates;
NÃO podemos invocar eventos a não ser nas próprias classes onde estes foram declarados;
Eventos possuem operadores definidos para assinar/cancelar assinatura;
Eventos DEVEM possuir uma assinatura específica (object sender, System.EventArgs e);
Para validar o terceiro ponto acima, crie um projeto e...
using System;
namespace EventosDelegates {
delegate void MeuHandler(string s);
class Classe1 {
public static event MeuHandler meuNotificador;
public static MeuHandler meuNotificador2;
static void Main(string[] args){
new Classe2().teste();
}
}
class Classe2 {
public void teste() {
Classe1.meuNotificador("teste"); // levanta um erro ...
// The event 'EventosDelegates.Class1.meuNotificador'
// can only appear on the left hand side
// of += or -= (except when used from within the type
// 'EventAndDelegate.Class1'
Classe1.meuNotificador2("teste2"); // compila 100%
}
}
}