1

我刚刚通过添加引用、将配置添加到 App.config 和 AssemblyInfo.cs 中的加载条目,在我的 C# WinForms 应用程序中设置了 log4net。配置设置为捕获所有级别。

在我的 Program.cs 中,我试图让它捕获每一个错误。

我目前有这个:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            try
            {
                log.Info("this works");
                Application.Run(new Forms.Main());
            }
            catch (Exception e)
            {
                log.Info("nothing here", e);
            }
        }
    }

我将“this works”放入只是为了测试我是否可以实际写入日志文件,这就是日志中显示的内容:

2012-09-30 23:00:53,959 [INFO ] - this works

我的 log4net 也设置为写入即时窗口,所以我故意创建了一些错误,这就是我在窗口中看到的内容:

ContractManagement.Program: 2012-09-30 23:08:09,177 [INFO ] - this works
A first chance exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll

我本来希望在日志中也看到第二个错误,但没有任何迹象:(


根据基思尼古拉斯的评论,我这样做了:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    log.Info("this works");
    throw new System.ArgumentException("Keith Nicholas Test");
    //Application.Run(new Forms.Main());

}

并且日志文件显示:

2012-09-30 23:19:12,090 [INFO ] - this works
System.ArgumentException: Keith Nicholas Test
   at ContractManagement.Program.Main() in c:\ContractManagement\ContractManagement\Program.cs:line 25
4

3 回答 3

1
A first chance exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll

这不是您的 log4net 配置的问题。其中一个内部库引发了异常,然后将其捕获,因此它永远不会出现在您的 catch 子句中。开发环境将捕获到的异常信息直接写到即时窗口中。

是的 log4net 正在写入即时窗口,但并非即时窗口中的所有内容都来自 log4net。

[更新 - 反映记录多个线程的更一般问题]

虽然与您的问题没有直接关系,但有时使用 log4net 日志记录的类可以同时在不同的线程中执行。您可以同时从多个线程获取调试、信息和/或错误方法。建议您更新 App.config 中的消息模式以包含线程,以便您可以跟踪哪个消息来自哪个线程。例如:

<conversionPattern value="%level %thread %logger - %message%newline" />

这只是一个示例 - 您没有包含您的转换模式,所以我不确定如果您要添加 %thread.

于 2012-09-30T22:20:04.303 回答
0

如果从一个新线程抛出一个异常,它不会被那个 catch 块捕获......

只是为了证明您的日志记录工作正常:-

而不是运行您的应用程序,只需在第一个 log.Info 之后立即抛出一个新的异常,以证明您的异常日志记录有效。

喜欢 :-

try
{
    log.Info("this works");
    throw new System.ArgumentException("Keith Nicholas Test");
}
catch (Exception e)
{
   log.Info("nothing here", e);
}
于 2012-09-30T22:14:17.167 回答
0

很多谷歌搜索后,我有:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    private static readonly ILog log = LogManager.GetLogger(typeof(Program));
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;

        Application.Run(new Forms.Main());
    }

    private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        log.Info(e.Exception.Message);
    }

    private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        log.Info(e);
    }

    static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
    {
        log.Info(e.Exception.Message);
    }
}

这捕获了我希望捕获的 FirstChanceExceptions:

2012-10-01 00:24:02,532 9 ContractManagement.Program [INFO ] - The database file cannot be found. Check the path to the database. [ Data Source = C:\ContractManagement\ContractManagement\bin\Debug\ContractManagement.sdf ]
于 2012-09-30T23:28:14.727 回答