我创建了一个用于 WPF 项目的日志记录助手。这是一个包含许多不同组件的大型项目。这是在我学会如何使用 MVVM 之前,所以如果这打破了模式,请原谅。该系统不断扩展新组件以处理不同的任务。您可以将组件视为处理特定任务的独立单元,主组件是所有组件的主人。这种日志记录使我们能够记录错误,无论它们发生在哪个组件中。这可能有点矫枉过正,但对我们来说效果很好。
我使用相同的原则来记录所有系统范围的事件(用户操作、数据更改..等)
在我的 App.xaml.cs 中,我捕获了所有未处理的错误。请注意,这是日志记录的最后手段,我使用 try catch 任何我希望发生异常的地方(例如数据库连接)。
public partial class App : Application
{
void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
ErrorEvent errorEvent = new ErrorEvent();
errorEvent.LogErrorEvent(e.Exception);
e.Handled = true;
}
}
ErrorEvent 是我的 Utilities 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
}