2011-01-19 14 views
7

Voglio sollevare una serie di eventi dal mio corso di biblioteca, ma sono preoccupato che alcuni sottoscrittori di eventi siano maleducati e impieghino molto tempo per elaborare alcuni eventi, bloccando così il thread che sta generando gli eventi. Pensavo di poter proteggere il filo raccolta utilizzando un thread pool di thread per raccogliere ogni evento:Posso usare BeginInvoke con MulticastDelegate?

if (packet != null && DataPacketReceived != null) 
{ 
    var args = new DataPacketEventArgs(packet); 
    DataPacketReceived.BeginInvoke(this, args, null, null); 
} 

che funziona bene quando c'è solo un abbonato alla manifestazione, ma non appena un secondo abbonato arriva, DataPacketReceived DIVENTA delegato multicast e ottengo un'eccezione di argomento con il messaggio di errore "Il delegato deve avere un solo target". C'è un modo semplice per aumentare l'evento su un thread separato, o devo avviare un thread e quindi generare l'evento da lì?

risposta

11

Ho trovato una domanda simile su another site e, naturalmente, Jon Skeet aveva risposto. Per il mio scenario, ho scelto per generare l'evento per ogni abbonato su un thread separato:

if (packet != null && DataPacketReceived != null) 
{ 
    var args = new DataPacketEventArgs(packet); 
    var receivers = DataPacketReceived.GetInvocationList(); 
    foreach (EventHandler<DataPacketEventArgs> receiver in receivers) 
    { 
     receiver.BeginInvoke(this, args, null, null); 
    } 
} 
+2

corretta, ma è da notare che la chiamata 'BeginInvoke' su ogni singolo abbonato non significa necessariamente che ogni verrà eseguito su un thread separato. È il business del pool di thread. – Ani

+1

Ho osservato questo problema un paio di volte negli ultimi giorni, È importante notare che gli oggetti in 'ricevitori' non sono in realtà di tipo' EventHandler ', questo è un cast esplicito. –