2010-03-20 11 views
2

J'ai une classe DirectoryMonitor qui fonctionne sur un autre thread. Il a les événements suivants a déclaré:Appel de EventHandler generic, TargetParameterCountException

public class DirectoryMonitor 
{ 
    public event EventHandler<MonitorEventArgs> CreatedNewBook; 
    public event EventHandler ScanStarted; 
    .... 
} 

public class MonitorEventArgs : EventArgs 
{ 
    public Book Book { get; set; } 
} 

Il y a un formulaire en utilisant ce moniteur, et lors de la réception des événements, il faut mettre à jour l'affichage.

Maintenant, cela fonctionne:

void DirectoryMonitor_ScanStarted(object sender, EventArgs e) 
    { 
     if (InvokeRequired) 
     { 
      Invoke(new EventHandler(this.DirectoryMonitor_ScanStarted)); 
     } 
     else {...} 
    } 

Mais cela jette TargetParameterCountException:

void DirectoryMonitor_CreatedNewBook(object sender, MonitorEventArgs e) 
    { 
     if (InvokeRequired) 
     { 
      Invoke(new EventHandler<MonitorEventArgs>(this.DirectoryMonitor_CreatedNewBook)); 
     } 
     else {...} 
    } 

Qu'est-ce que je manque?

Répondre

2

La méthode Invoke permet de recevoir une instance System.Delegate pouvant être invoquée sans passer de paramètre supplémentaire. Le délégué créé en utilisant DirectoryMonitor_ScanStarted nécessite 2 paramètres et par conséquent vous obtenez l'exception lorsqu'il est utilisé.

Vous devez créer un nouveau délégué qui encapsule l'appel et les arguments ensemble.

MethodInvoker del =() => this.DirectoryMonitor_ScanStarted(sender,e); 
Invoke(del); 
+0

Merci pour la solution. Bien que je ne comprends toujours pas pourquoi le premier événement est déclenché, mais le second jette l'exception. – Amirshk

+0

J'ai eu le même comportement étrange. Un Invoke a travaillé et l'autre pas. La "clé" était que l'Invoke actif utilisait une simple classe dérivée de EventArgs sans aucun ajout et que l'invocation non-active utilisait une classe dérivée de EventArgs avec des champs supplémentaires (comme votre MonitorEventArgs). Il semble que le premier cas soit ignoré pendant la réflexion, mais pas le second. – Mike

0

vous manquez les paramètres: -

void DirectoryMonitor_ScanStarted(object sender, MonitorEventArgs e) 
    { 
     if (InvokeRequired) 
     { 
      Invoke(new EventHandler<MonitorEventArgs>(DirectoryMonitor_ScanStarted), sender, e); 
     } 
     else {...} 
    } 

Pour des raisons pas claires pour moi (probablement à cause de l'héritage COM), il est permis d'omettre les paramètres lors de l'utilisation d'un événement générique, mais pas lors de l'utilisation un type EventArg défini par l'utilisateur.