[英]Handling AppDomain.CurrentDomain.UnhandledException in windows service
[英]How can I set up .NET UnhandledException handling in a Windows service?
protected override void OnStart(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Thread.Sleep(10000);
throw new Exception();
}
void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
}
我在我的Windows服務中將調試器附加到上面的代碼,在CurrentDomain_UnhandledException中設置斷點,但它從未被命中。 彈出的異常是說它未處理,然后服務停止。 我甚至嘗試在事件處理程序中放入一些代碼,以防它被優化掉。
這不是在Windows服務中設置未處理的異常處理的正確方法嗎?
當前AppDomain上的UnhandledException
事件未觸發的原因是服務的執行方式。
ServiceBase
實現接收,並分派給OnStart
方法。 OnStart
方法。 OnStart
拋出的任何異常都在基類中處理 ,記錄到事件日志中,並轉換為返回給SCM的錯誤狀態代碼。 因此,異常永遠不會傳播到AppDomain的未處理異常處理程序。
我認為您會發現從您的服務中的工作線程拋出的未處理異常將被AppDomain的未處理異常處理程序捕獲。
在Windows服務中,您不希望在OnStart方法中運行太多代碼。 您只需要啟動服務線程然后返回的代碼。
如果這樣做,您可以處理服務線程中發生的異常。
例如
public static void Start()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
running = true;
ThreadStart ts = new ThreadStart(ServiceThreadBody);
thread = new Thread(ts);
thread.Name = "ServiceThread";
thread.Priority = ThreadPriority.BelowNormal;
thread.Start();
}
知道這個線程有點舊,但認為根據在.NET中開發Windows服務的個人經驗添加一些注釋會很有用。 最好的方法是盡可能避免在服務控制管理器下進行開發 - 為此你需要一個模擬服務啟動方式的簡單工具 - 可以創建服務類實例的東西(你已經從ServiceBase派生的) )並調用您的OnStart,OnStop等方法。 根據需要,此線束可以是控制台應用程序或Windows應用程序。
這幾乎是我在.NET中調試服務啟動問題的唯一方法 - 您的代碼,Visual Studio和真正的服務控制管理器之間的交互只會使該過程無法實現。
HTH。
當我在自己的Windows服務上工作時,它已經奇怪地停止了。 我以為是因為無恥的例外。 目前我正在文本文件中捕獲無法處理的異常。 首先,由於在文本文件上記錄了excaptions,您必須在C位置創建新文件ServiceLog.txt。 在下面的編碼中,我得到了所有未加掩蓋的例外情況。
using System.Security.Permissions;
using System.IO;
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
protected override void OnStart(string[] args)
{ AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
...
Your codes...
....
}
void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
WriteToFile("Simple Service Error on: {0} " + e.Message + e.StackTrace);
}
private void WriteToFile(string text)
{
string path = "C:\\ServiceLog.txt";
using (StreamWriter writer = new StreamWriter(path, true))
{
writer.WriteLine(string.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
writer.Close();
}
}
只是好奇,你想要完成什么:避免服務崩潰,或報告錯誤?
對於報告,我認為最好的辦法是添加頂級的try / catch語句。 您可以嘗試將它們記錄到Windows事件日志和/或日志文件中。
您還可以將ExitCode屬性設置為非零值,直到您成功停止服務。 如果系統管理員從“服務”控制面板啟動服務,並且您的服務突然停止並使用非零退出代碼,則Windows可以顯示包含錯誤描述的錯誤消息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.