我正在使用带有WinForms的ABP框架,我需要找出拦截异常并记录此信息的最佳方法。
我的WinForms是一个多文档界面(MDI)应用程序。我在 Program.cs 中添加HandleException
,以便在应用程序抛出异常时,我可以将其记录在日志文件中。但是如果我在ApplicationService
中得到一个异常,这个异常由ABP处理而不会被抛回WinForms,并且没有任何内容写入日志文件。
我是否需要实现一些接口来获得像MVC / Angular app这样的经典日志?
更新
我发现问题与异步操作有关。通常我打电话:
await _service.GetProducts();
如果抛出异常,主线程不会拦截它。如果我切换到:
AsyncHelper.RunSync(() => _service.GetProducts());
然后主线程拦截错误。
答案 0 :(得分:0)
因为在另一个线程中抛出异常,您必须处理应用程序域的未处理异常。将异常处理程序插入应用程序的起始点。对于win表单,我猜你可以使用program.cs
static class Program
{
[STAThread]
static void Main(string[] argv)
{
try
{
AppDomain.CurrentDomain.UnhandledException += (sender,e)
=> HandleException(e.ExceptionObject);
Application.ThreadException += (sender,e)
=> HandleException(e.Exception);
Application.Run(new MainWindow());
}
catch (Exception ex)
{
HandleException(ex);
}
}
static void HandleException(object exception) {
var ex= exception as Exception;
if (ex== null) {
ex= new NotSupportedException("Unhandled exception: " + exceptionObject.ToString());
}
//you can log exception here -> ex.ToString();
}
}
答案 1 :(得分:0)
在进行了一些调查和谷歌搜索之后,我发现了这个MSDN解释Asynchronous Programming - Async from the Start
根据这篇文章我改变我的程序开始转移到异步代码。 我需要更多一点,因为我在打开内部表格时使用Mdi表格
Form1 childForm = Globals.Bootstrapper.IocManager.Resolve<Form1>();
childForm.MdiParent = this;
var formAsync = childForm.InitializeAsync();
FormExtension.HandleExceptions(formAsync);
childForm.Show();
我添加静态类来拦截错误形式Abp
public static async void HandleExceptions(Task task)
{
try
{
await Task.Yield(); //ensure this runs as a continuation
await task;
}
catch (Exception ex)
{
//deal with exception, either with message box
//or delegating to general exception handling logic you may have wired up
//e.g. to Application.ThreadException and AppDomain.UnhandledException
var log = Globals.Bootstrapper.IocManager.IocContainer.Resolve<ILogger>();
LogHelper.LogException(log, ex);
//Exception handling...
MessageBox.Show("Ops!" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
//Application.Exit();
}
}
现在我的日志文件以正确的方式填充