2012-10-30 12 views
5

Ho un evento che funziona correttamente quando si esegue in modalità test, ma non si attiva quando eseguo il codice come servizio. Prima di pubblicare il codice, vorrei dare un po 'di struttura per l'applicazione, poiché ritengo che questo sia il punto in cui il problema si sta verificando.Evento non attivo quando è in esecuzione come servizio

Ho un'app tray che viene utilizzata per controllare un servizio router. Quando viene avviato, il servizio carica una libreria DLL in cui avviene tutta l'elaborazione. Quando la libreria viene avviata, analizza una directory per i plug-in e li collega al programma principale.

Quando viene generato come Release, il servizio è attivato e devo installare l'applicazione. Come nota a margine, l'app del vassoio viene eseguita come amministratore in modo da poter controllare il servizio. Quando si costruisce come Debug, il vassoio avvia direttamente la DLL della libreria, saltando la piccola app di servizio che la avvia. Vedere lo schema qui di seguito:

enter image description here

In entrambi i casi, il flusso di questo plugin è un ricevitore riceve un file, e notifica un mittente di trasmetterla attraverso un evento. Il file viene inviato per l'elaborazione remota e quindi restituito a un altro ricevitore, che inoltra i risultati al plug-in attraverso un evento. Il plugin elabora quindi il file e deve ritornare al programma principale in un evento. Quando si esegue in Debug (nessun servizio), questo è esattamente ciò che accade. Quando si esegue come un servizio, tutta la gestione degli eventi funziona perfettamente tranne che per il plugin che notifica al programma principale che i risultati sono stati elaborati. Non ci sono eccezioni generate, e ho confermato attraverso la registrazione che l'evento è stato collegato correttamente.

Collegamento evento:

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

Chiamando l'evento dal plugin:

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) 
     { ... } 
    } 
} 

Secondo i registri, il plugin è collegato correttamente su OnProcessed e l'accesso al metodo ExtractResults() mostra che sta ritornando correttamente. Tuttavia, NotifyProcessingComplete non chiama il metodo OnProcessed.

Ancora una volta, ciò accade solo quando si esegue il codice come servizio. Sospetto che possa avere qualcosa a che fare con il vassoio che funziona come amministratore, il servizio in esecuzione come sistema locale e il plugin caricato dinamicamente.

Di seguito ho inserito il mio codice per il caricamento di un plugin, nel caso in cui potrebbe essere 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); 
     } 
    } 
} 

Qualsiasi aiuto o suggerimenti sarebbe molto apprezzato. Grazie in anticipo.

+1

Prova ad esaminare la funzione ExtractResults, sembra che qualcosa vada storto lì ... – Dusan

+0

@Dusan - Grazie per il tuo commento. Ho riempito il metodo con i messaggi di log e so che tutto funziona come previsto fino al ritorno. Ho anche esaminato l'oggetto che stava tornando, che è stato creato come doveva essere. Tuttavia, solo per essere assolutamente positivo, ho appena inviato un nuovo oggetto piuttosto che ottenerlo dal metodo e questo ha causato alcuni errori imprevisti. Da ciò, sono stato in grado di rintracciare l'errore in un problema di accesso SQL nel metodo OnProcessed. Grazie ancora per il tuo suggerimento.Se crei una risposta, sarei felice di darti credito. – Tim

+0

Sembra un problema di autorizzazioni, puoi provare a modificare l'account utente utilizzato dal servizio e vedere se funziona? –

risposta

0

È possibile verificare se gli oggetti ricevitore/mittente non sono GC? Questo potrebbe essere il caso, poiché il tuo modello di inizializzazione per il rilascio e il debug sono diversi

Problemi correlati