2012-10-30 14 views
5

Ich habe ein Ereignis, das im Testmodus einwandfrei funktioniert, aber nicht ausgeführt wird, wenn ich den Code als Dienst ausführen. Bevor ich den Code poste, möchte ich ein wenig Struktur für die Anwendung geben, da ich der Meinung bin, dass das Problem dort liegt.Ereignis nicht ausgelöst, wenn als Dienst ausgeführt wird

Ich habe eine Tray-App, die verwendet wird, um einen Router-Dienst zu steuern. Beim Start lädt der Dienst eine DLL-Bibliothek, in der die gesamte Verarbeitung stattfindet. Wenn die Bibliothek gestartet wird, durchsucht sie ein Verzeichnis nach Plug-Ins und hakt sie in das Hauptprogramm ein.

Wenn als Release erstellt, ist der Dienst aktiviert, und ich muss die Anwendung installieren. Als Randnotiz wird die Tray-App als Administrator ausgeführt, um den Dienst zu steuern. Beim Erstellen als Debug startet das Tray die Library-DLL direkt und überspringt die kleine Service-App, die es startet. Siehe Diagramm unten:

enter image description here

In jedem Fall wird der Fluss für dieses Plugin ist ein Empfänger eine Datei empfängt, und benachrichtigt einen Sender es durch ein Ereignis zu übermitteln. Die Datei wird für die Remoteverarbeitung gesendet und dann an einen anderen Empfänger zurückgegeben, der die Ergebnisse über ein Ereignis an das Plugin weiterleitet. Das Plugin verarbeitet dann die Datei und sollte in einem Event an das Hauptprogramm zurückgesendet werden. Wenn das in Debug (kein Dienst) ausgeführt wird, geschieht genau das. Bei der Ausführung als Dienst funktioniert die gesamte Ereignisbehandlung einwandfrei, außer dass das Plugin dem Hauptprogramm mitteilt, dass die Ergebnisse verarbeitet wurden. Es gibt keine Ausnahmen, und ich habe durch Protokollierung bestätigt, dass das Ereignis korrekt verbunden war.

das Ereignis anschließen:

// 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); 
} 

das Ereignis aus der Plugin-Aufruf:

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

Event-Handler:

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

den Protokollen nach, wird das Plugin korrekt angeschlossen zu OnProcessed, und Anmeldung der ExtractResults() - Methode zeigt, dass es korrekt zurückgibt. NotifyProcessingComplete ruft jedoch die OnProcessed-Methode nicht auf.

Dies geschieht wiederum nur, wenn der Code als Dienst ausgeführt wird. Ich vermute, dass es etwas damit zu tun hat, dass das Tablett als Administrator läuft, der Dienst als Lokales System läuft und das Plugin dynamisch geladen wird.

Unten habe ich meinen Code enthalten ein Plugin zum Laden, falls könnte es helfen:

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); 
     } 
    } 
} 

Jede Hilfe oder Anregungen wäre sehr dankbar. Vielen Dank im Voraus.

+1

Versuchen Sie, ExtractResults Funktion zu untersuchen, scheint wie etwas schief geht da ... – Dusan

+0

@Dusan - Vielen Dank für Ihren Kommentar. Ich habe die Methode mit Log-Postings gefüllt und weiß, dass bis zur Rückgabe alles wie erwartet läuft. Ich untersuchte auch das Objekt, das es zurückgab, das so erstellt wurde, wie es sein sollte. Um jedoch absolut positiv zu sein, habe ich einfach ein neues Objekt gesendet, anstatt es von der Methode zu bekommen, was einige unerwartete Fehler verursachte. Von diesem konnte ich den Fehler zu einem SQL-Anmeldungsproblem in der OnProcessed-Methode aufspüren. Nochmals vielen Dank für Ihren Vorschlag.Wenn Sie eine Antwort erstellen, würde ich Ihnen gerne Kredit geben. – Tim

+0

Klingt nach einem Berechtigungsproblem, können Sie versuchen, das vom Dienst verwendete Benutzerkonto zu optimieren und sehen, ob das funktioniert? –

Antwort

0

Können Sie überprüfen, ob die Empfänger-/Senderobjekte nicht als GED angezeigt werden? Dies kann der Fall sein, da Ihr Initialisierungsmuster für Release und Debug unterschiedlich sind

Verwandte Themen