2015-04-28 1 views
0

J'ai une classe statique handler interaction de base de données MS SQL avec un gestionnaire d'événements comme celui-ci:C# gérer plusieurs événements pour un événement

public static event EventHandler<SQLExceptionEventArgs> SQLExceptionCaught; 

alors j'ai une fonction pour gérer:

private static void OnSQLExceptionCaught(SqlException e) 
{ 
    if (SQLExceptionCaught != null) 
    { 
     SQLExceptionCaught(SQLExceptionCaught.Target, new SQLExceptionEventArgs(e)); 
    } 
} 

J'ai aussi un formulaire personnalisé héritée de Windows.Forms.Form qui ajoute un délégué à ce gestionnaire d'événements:

DBHandler.SQLExceptionCaught += this.handleSQLException; 

(il est supprimé lorsque le formulaire se ferme)

puis ce délégué est remplacé dans chaque formulaire.

Cela fonctionne correctement quand un seul formulaire est ouvert, mais je ne peux pas le faire fonctionner pour plusieurs formulaires afin qu'il tire uniquement le délégué du formulaire qui a réellement déclenché l'événement.

Pourriez-vous me diriger dans la bonne direction? Est-ce même possible?

Je considérerais volontiers n'importe quelle autre solution tant qu'elle conserverait cette fonctionnalité.

+0

Cela n'a aucun sens. Vous ne pouvez pas vraiment faire cela avec un seul gestionnaire de base de données global, sauf si vous passez le formulaire avec chaque requête/commande. En fait, c'est exactement le point où vous envoyez 'SQLExceptionCaught.Target', plutôt que le véritable * expéditeur *. Si chaque requête/commande passe l'expéditeur (le formulaire qui a provoqué l'exécution de cette requête), vous pouvez juste comparer l'expéditeur à 'this' dans le gestionnaire, et savoir si c'est" votre "exception ou non. Mais vous préférerez probablement conserver une instance distincte du gestionnaire de base de données de toute façon. – Luaan

Répondre

4

Il me semble que vous devriez transformer votre classe statique en une classe non statique. Ensuite, vous avez un événement instance et deux instances de la classe (une par formulaire). À ce stade, les deux gestionnaires d'événements seraient séparés de manière appropriée. Fondamentalement, vous partagez de manière inappropriée pour le moment. En outre, votre code actuel peut afficher NullReferenceException en raison de la valeur de SQLExceptionCaught devenant nulle après la vérification, mais avant la ligne suivante. En général, vous souhaitez résoudre ce en utilisant une variable locale:

private static void OnSQLExceptionCaught(SqlException e) 
{ 
    var handler = SQLExceptionCaught; 
    if (handler != null) 
    { 
     handler(SQLExceptionCaught.Target, new SQLExceptionEventArgs(e)); 
    } 
} 

Il existe d'autres options autour des méthodes d'extension et l'opérateur conditionnel nul introduit en C# 6 ... voir my blog post on the topic pour plus de détails.

0

Vous pouvez trouver le problème folows:

  • Ouvrez plusieurs formes.
  • Définissez un point d'arrêt dans votre OnSQLExceptionCaught.
  • À ce stade, vérifiez le contenu de l'événement SQLExceptionCaught à l'aide de la méthode GetInvocationList. S'il n'a qu'un seul formulaire en tant qu'abonné, vérifiez votre code qui s'abonne à votre événement.
  • S'il y a plus d'un abonné, et qu'un seul abonné est appelé, assurez-vous que l'abonné ne lance PAS une exception. Si une exception est levée lors de l'appel d'un événement, les autres abonnés ne sont pas appelés.