運行時,我在測試模式下運行時工作得很好,但是當我運行的代碼作爲服務不火的事件不點火。在我發佈代碼之前,讓我介紹一下應用程序的結構,因爲我覺得這是問題的起因。事件作爲服務
我有一個用來控制一個路由器服務的托盤的應用程序。啓動時,該服務會加載一個所有處理髮生的dll庫。當庫啓動時,它會掃描目錄中的插件,並將它們掛接到主程序中。
當作爲發佈建成,該服務被激活了,我必須安裝應用程序。作爲一個側面說明,托盤應用程序以管理員身份運行,因此它可以控制服務。當構建爲Debug時,該托盤直接啓動庫DLL,跳過啓動它的小型服務應用程序。請參見下面的圖:
在任一情況下,此插件的流動是一個接收器接收到的文件,並通知發送方通過一個事件轉發它。該文件被髮送以進行遠程處理,然後返回到另一個Receiver,該Receiver通過事件將結果轉發給插件。然後該插件處理該文件,並且應該在事件中發送回主程序。在Debug(無服務)下運行時,這正是發生的情況。作爲服務運行時,除了通知主程序處理結果的插件外,所有的事件處理都可以完美工作。沒有拋出異常,並且我已通過日誌記錄證實事件已正確連接。
連接事件:
// 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);
}
調用從插件事件:
if (NotifyProcessingComplete != null)
NotifyProcessingComplete(ExtractResults(args.ReceivedFile));
else
LogWriter.Log("NotifyProcessingComplete Delegate was null.", LogFile);
事件處理程序:
public void OnProcessed(ProcessArgs args)
{
LogWriter.Log("On Dicom Process was called...", LogFile);
lock (threadLock)
{
if (Settings != null)
{ ... }
}
}
根據日誌,該插件正確掛接到OnProcessed,並且登錄到ExtractResults()方法表明它正確地返回。但是,NotifyProcessingComplete不調用OnProcessed方法。
再次,運行代碼作爲一種服務時,這是唯一的發生。我懷疑它可能與以管理員身份運行的托盤,以本地系統身份運行的服務以及正在動態加載的插件有關。
下面我包括我的加載插件代碼,在情況下,它可能會幫助:
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);
}
}
}
任何幫助或建議,將不勝感激。先謝謝你。
嘗試檢查ExtractResults功能,似乎是不順心的事有... – Dusan
@Dusan - 謝謝你的評論。我用日誌帖子填充了方法,並知道一切都按預期運行,直到回報。我還檢查了它正在返回的對象,它是按照它應該創建的。但是,爲了絕對肯定,我只是發送了一個新對象,而不是從方法中獲取它,並導致了一些意外錯誤。從那以後,我能夠在OnProcessed方法中追蹤到SQL登錄問題的錯誤。再次感謝您的建議。如果您創建回覆,我會很樂意爲您提供信用。 – Tim
聽起來像一個權限問題,你可以嘗試調整服務使用的用戶帳戶,看看是否有效? –