我創建了一個用於我的WPF項目的日誌助手。這是一個包含許多不同組件的大型項目。這是在我學習如何使用MVVM之前,所以請原諒,如果這打破了這種模式。這個系統正在不斷擴大,新組件可以處理不同的任務。您可以將組件視爲處理特定任務的獨立單元,其中主要組件是它們的主要組件。這個記錄允許我們記錄錯誤,不管它們發生在哪個組件中。這可能是一種矯枉過正,但對我們來說工作得非常好。
我使用的是同樣的原理來記錄所有系統級事件(用戶操作,數據Changes..etc)
在我App.xaml.cs我捕捉所有未處理的錯誤。請注意,這是日誌記錄的最後手段,我使用嘗試捕獲任何我希望發生異常的地方(例如db連接)。
public partial class App : Application
{
void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
ErrorEvent errorEvent = new ErrorEvent();
errorEvent.LogErrorEvent(e.Exception);
e.Handled = true;
}
}
ErrorEvent是我的公用事業DLL中的一個類,它使用事件路由記錄錯誤。根據嚴重程度,我有不同類型的錯誤。所有這些錯誤都記錄在數據庫中,唯一知道數據庫連接的組件是主要的。這就是爲什麼我使用路由事件將異常發送到要記錄的主要組件。ErrorEventHelper被填充並路由到主要組件。在使用try catch的情況下,我創建EventHelper並使用LogErrorEvent方法將其傳遞給日誌。 ShowMessage屬性用於決定用戶是否會通知異常,或者是否僅記錄。
public class ErrorEvent : UserControl
{
public delegate void ErrorEventEventHandler(object sender, RoutedCustomEventArgs e);
public static readonly RoutedEvent EventOccuredEvent = EventManager.RegisterRoutedEvent(
"EventOccured", RoutingStrategy.Bubble, typeof(ErrorEventEventHandler), typeof(ErrorEvent));
// Provide CLR accessors for the event
public event RoutedEventHandler EventOccured
{
add { AddHandler(EventOccuredEvent, value); }
remove { RemoveHandler(EventOccuredEvent, value); }
}
public void LogErrorEvent(ErrorEventHelper occuredEventDetails)
{
RoutedEventArgs newEventArgs = new RoutedCustomEventArgs(ErrorEvent.EventOccuredEvent, occuredEventDetails);
RaiseEvent(newEventArgs);
}
public void LogErrorEvent(Exception exception)
{
ErrorEventHelper occuredEventDetails = new ErrorEventHelper();
occuredEventDetails.ErrorType = ErrorEventHelper.EventTypes.Critical;
occuredEventDetails.ErrorValue = exception.Message;
occuredEventDetails.ErrorStack = exception.StackTrace;
occuredEventDetails.ShowMessage = true;
RoutedEventArgs newEventArgs = new RoutedCustomEventArgs(ErrorEvent.EventOccuredEvent, occuredEventDetails);
RaiseEvent(newEventArgs);
if (exception.InnerException != null)
{
LogErrorEvent(exception.InnerException);
}
}
public class RoutedCustomEventArgs : RoutedEventArgs
{
public ErrorEventHelper OccuredEventDetails { get; private set; }
public RoutedCustomEventArgs(RoutedEvent routedEvent, ErrorEventHelper occuredEventDetails)
: base(routedEvent)
{
this.OccuredEventDetails = occuredEventDetails;
}
}
}
public class ErrorEventHelper
{
public string ErrorValue { get; set; }
private EventTypes _ErrorType = EventTypes.Critical;
public EventTypes ErrorType
{
get
{
return _ErrorType;
}
set
{
_ErrorType = value;
}
}
public string ErrorStack { get; set; }
public bool ShowMessage { get; set; }
public enum EventTypes
{
Critical,
Warning,
Information
}
public void SendMessage()
{
ErrorEvent newEvent = new ErrorEvent();
newEvent.LogErrorEvent(this);
}
}
在MainWindow中,我註冊了事件處理程序。
EventManager.RegisterClassHandler(typeof(ErrorEvent),
ErrorEvent.EventOccuredEvent, new ErrorEvent.ErrorEventEventHandler(LogOccuredErrors));
最後處理:
private void LogOccuredErrors(object sender, ErrorEvent.RoutedCustomEventArgs e)
{
ErrorEventHelper eventHelper = e.OccuredEventDetails;
//Call Database Helper to log to database or output to file and email
StringBuilder builder = new StringBuilder();
builder.AppendLine(eventHelper.ErrorType);
builder.AppendLine(eventHelper.ErrorValue);
builder.AppendLine(eventHelper.ErrorStack);
if (eventHelper.ShowMessage)
{
MessageBox.Show(eventHelper.ErrorValue);
}
//Create your log file and email it
File.WriteAllText(@"C:\log.txt", ControllerBuilder.ToString())
//email here
}
你並不需要把嘗試趕上無處不在,也許需要了解處理異常的最佳做法;請參閱http://stackoverflow.com/questions/183589/best-practice-for-exception-handling-in-a-windows-forms-application – 2012-07-18 16:58:40