2012-10-30 3 views
5

J'ai un événement qui marche très bien en mode test, mais qui ne se déclenche pas lorsque j'exécute le code en tant que service. Avant de poster le code, permettez-moi de donner un peu de structure à l'application, car je pense que c'est là que le problème se pose.L'événement ne se déclenche pas en cours d'exécution en tant que service

J'ai une application de plateau qui est utilisée pour contrôler un service de routeur. Au démarrage, le service charge une bibliothèque dll où tout le traitement a lieu. Lorsque la bibliothèque est démarrée, elle analyse un répertoire pour les plug-ins et les connecte au programme principal.

En version Release, le service est activé et je dois installer l'application. En remarque, l'application de plateau est exécutée en tant qu'administrateur afin de pouvoir contrôler le service. Lors de la construction en tant que débogage, le plateau démarre directement la DLL de la bibliothèque, en ignorant l'application de service de petite taille qui le démarre. Voir le schéma ci-dessous:

enter image description here

Dans les deux cas, le flux de ce plug-in est un récepteur reçoit un fichier, et notifie à un expéditeur de le transmettre par un événement. Le fichier est envoyé pour traitement à distance, puis renvoyé à un autre récepteur, qui transmet les résultats au plug-in via un événement. Le plugin traite alors le fichier, et devrait renvoyer au programme principal dans un événement. Lors de l'exécution dans Debug (pas de service), c'est exactement ce qui se passe. Lors de l'exécution en tant que service, toute la gestion des événements fonctionne parfaitement à l'exception du plugin notifiant le programme principal que les résultats ont été traités. Aucune exception n'a été levée, et j'ai confirmé par la connexion que l'événement était correctement connecté.

Connexion de l'événement:

// Connect delegate to plugins that will add data to the database through the Router 
if (plugin is INotify) 
{ 
    ((INotify)plugin).NotifyProcessingComplete += new ProcessNotification(this.OnProcessed); 
    LogWriter.Log("Associated " + plugin.Name + " with OnProcessed", LogFile); 
} 

Appeler l'événement du plug-in:

if (NotifyProcessingComplete != null) 
    NotifyProcessingComplete(ExtractResults(args.ReceivedFile)); 
else 
    LogWriter.Log("NotifyProcessingComplete Delegate was null.", LogFile); 

Gestionnaire de l'événement:

public void OnProcessed(ProcessArgs args) 
{ 
    LogWriter.Log("On Dicom Process was called...", LogFile); 
    lock (threadLock) 
    { 
     if (Settings != null) 
     { ... } 
    } 
} 

Selon les journaux, le plug-in est accroché correctement à OnProcessed, et la connexion dans la méthode ExtractResults() montre qu'il retourne correctement. Toutefois, NotifyProcessingComplete n'appelle pas la méthode OnProcessed.

Encore une fois, cela ne se produit que lors de l'exécution du code en tant que service. Je soupçonne qu'il peut avoir quelque chose à faire avec le plateau fonctionnant en tant qu'administrateur, le service s'exécutant en tant que système local, et le plugin étant chargé dynamiquement.

Ci-dessous j'ai inclus mon code pour charger un plug-in, dans le cas où il pourrait être utile:

private void loadPlugins() 
{ 
    String pluginPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 

    // Create a domain to text for plugins 
    AppDomain domain = AppDomain.CreateDomain("PluginLoader"); 

    PluginFinder finder = (PluginFinder)domain.CreateInstanceAndUnwrap(
     typeof(PluginFinder).Assembly.FullName, typeof(PluginFinder).FullName); 
    finder.LogFile = logFile; 

    // Get valid plugins, and then unload the domain to clear up memory 
    List<String> FoundPluginTypes = finder.SearchPath(pluginPath); 
    AppDomain.Unload(domain); 

    // Load the plugins 
    Plugins = new List<IPlugin>(); 
    foreach (String plugin in FoundPluginTypes) 
    { 
     Assembly assembly = Assembly.LoadFrom(plugin); 
     Type type = null; 

     foreach (Type t in assembly.GetTypes()) 
      if (t.GetInterface("IPlugin") != null) 
       type = t; 

     try 
     { 
      IPlugin loader = (IPlugin)Activator.CreateInstance(type); 
      Plugins.Add(loader); 
     } 
     catch (NullReferenceException e) 
     { 
      LogWriter.Log("Could not load plugin.", e, LogFile); 
     } 
    } 
} 

Toute aide ou suggestions seraient grandement appréciés. Merci d'avance.

+1

Essayez d'examiner la fonction ExtractResults, il semble que quelque chose ne va pas là ... – Dusan

+0

@Dusan - Merci pour votre commentaire. J'ai rempli la méthode avec des messages de journal, et je sais que tout se déroule comme prévu jusqu'au retour. J'ai également examiné l'objet qu'il retournait, qui a été créé comme il était censé être. Cependant, juste pour être absolument positif, j'ai juste envoyé un nouvel objet plutôt que de l'obtenir de la méthode, et cela a causé quelques erreurs inattendues. De cela, j'ai été capable de localiser l'erreur à un problème de connexion SQL dans la méthode OnProcessed. Merci encore pour votre suggestion.Si vous créez une réponse, je serais heureux de vous donner un crédit. – Tim

+0

Cela ressemble à un problème d'autorisations, pouvez-vous essayer de peaufiner le compte d'utilisateur utilisé par le service et voir si cela fonctionne? –

Répondre

0

Pouvez-vous vérifier si les objets Récepteur/Expéditeur ne sont pas GCés? Cela peut être le cas, car votre modèle d'initialisation pour la libération et le débogage sont différents

Questions connexes