简体   繁体   English

用于日志记录的C#类库中未处理的异常

[英]Unhandled Exceptions in C# Class Library for Logging Purposes

I am new to software development and also new to stackoverflow, so go easy on me. 我是软件开发的新手,也是stackoverflow的新手,所以对我来说很容易。

BACKGROUND: I am developing a C# class library that processes xml messages sent by a third party application over tcp/ip (using Async sockets). 背景:我正在开发一个C#类库,它通过tcp / ip处理第三方应用程序发送的xml消息(使用异步套接字)。 I am using com-interop in order to expose the class library to a Vb6 application. 我正在使用com-interop将类库公开给Vb6应用程序。 When the C# library processes the xml it receives over the socket, it raises various events that the consuming vb6 application subscribes to (this way, when we eventually rewrite the entire application in .Net we will already be done with this component). 当C#库处理它通过套接字接收的xml时,它会引发消费vb6应用程序订阅的各种事件(这样,当我们最终在.Net中重写整个应用程序时,我们已经完成了这个组件)。

QUESTION: I want to catch all unhandled exceptions for LOGGING PURPOSES ONLY. 问题:我想捕获所有仅用于登录的未处理异常。 In a winforms application you can hook up an event to the AppDomain.CurrentDomain.UnhandledException and to Application.ThreadException. 在winforms应用程序中,您可以将事件连接到AppDomain.CurrentDomain.UnhandledException和Application.ThreadException。 Is there no way to similarly grab exception data to log the information in a class library? 有没有办法同样抓取异常数据来记录类库中的信息?

Important Points: 重点:

  • I am not trying to recover from these exceptions, but just log them and let the exception propogate up and crash the app if need be. 我不是试图从这些异常中恢复,而只是记录它们并让异常传播并在需要时崩溃应用程序。

  • I am doing my best to catch all specific exceptions locally wherever I know that they might occur. 我正在尽力在本地捕获所有特定异常,无论我知道它们可能发生在哪里。 Therefore my purpose is to just log the truly unexpected exceptions. 因此,我的目的是记录真正意外的异常。

  • I know that some will say that this would be a bad design pattern. 我知道有人会说这将是一个糟糕的设计模式。 I should instead let the caller deal with these exceptions. 我应该让调用者处理这些异常。 The problem is the vb6 application does not have as robust error handling in place as I would like. 问题是vb6应用程序没有像我想的那样具有强大的错误处理能力。 Primarily, I want to log the stack trace so that if the vb6 app crashes due to my dll, I can view the log in order to be alerted to potential areas of my c# code that might need to be changed. 首先,我想记录堆栈跟踪,以便如果vb6应用程序因我的dll而崩溃,我可以查看日志,以便提醒我可能需要更改的c#代码的潜在区域。

Can anyone provide me with some direction? 任何人都可以为我提供一些方向吗? The best option that I have found so far seems to put a generic try catch block in every public method, log the exception, and then throw it. 到目前为止,我发现的最佳选项似乎是在每个公共方法中放置一个通用的try catch块,记录异常,然后抛出它。 This seems less than ideal: 这似乎不太理想:

public void SomeMethod()
{
    try
    {
        // try something here...
    }
    catch (Exception ex)
    {
        Log(ex);
        throw;
    }
}

Not only does this seem like a poor design, but additionally I do not know what would happen if one of the async callbacks causes an exception on a different thread than the method was called on. 这不仅看起来像一个糟糕的设计,而且我不知道如果其中一个异步回调在不同的线程上导致异常而不是调用该方法会发生什么。 Would this general try/catch block still catch such an exception? 这个通用的try / catch块是否仍会捕获这样的异常?

Thanks for any assistance. 谢谢你的帮助。

EDIT: I originally marked @Eric J.'s answer as correct, but after trying to implement the solution I have found that it won't work well with the async callbacks from the socket class that I am using. 编辑:我最初标记@Eric J.的答案是正确的,但在尝试实现解决方案后,我发现它不能很好地处理我正在使用的套接字类的异步回调。 Once a threadpool thread is used to fire the async callback, I cannot seem to catch any exceptions that occur any later in the stack. 一旦使用线程池线程来触发异步回调,我似乎无法捕获堆栈中稍后发生的任何异常。 Will I need to use an AOP framework, or is there any other way to catch these exceptions? 我是否需要使用AOP框架,还是有其他方法来捕获这些异常?

If you have a limited set of entry points to the library, consider doing just what you suggest - use a .NET wrapper class or wrapper library to perform the actual interop and catch/log the exception in that wrapper class. 如果您对库有一组有限的入口点,请考虑按照您的建议 - 使用.NET包装器类或包装器库来执行实际的互操作,并在该包装器类中捕获/记录异常。 Return an exception or error code that the calling VB6 library knows how to handle (whether that's rethrowing the exception or not depends on what the VB6 code can deal with). 返回一个异常或错误代码,调用VB6库知道如何处理(是否重新抛出异常取决于VB6代码可以处理什么)。

CrazyDart suggests IOC, which is an interesting and valid alternative but also adds complexity and learning curve initially. CrazyDart建议IOC,这是一个有趣且有效的替代方案,但最初也增加了复杂性和学习曲线。 Certainly have a look at IOC as well and concider it as a possibility. 当然也要看看IOC并将其作为一种可能性。

You could use Castle Windsor and an interceptor for this. 你可以使用Castle Windsor和拦截器。 Its a good reason to use IOC on projects. 这是在项目上使用IOC的一个很好的理由。

http://blog.andreloker.de/post/2009/02/20/Simple-AOP-integrating-interceptors-into-Windsor.aspx http://blog.andreloker.de/post/2009/02/20/Simple-AOP-integrating-interceptors-into-Windsor.aspx

I have used them for exception logging, just as you stated, and performance logging... among many other things you use interceptors for like transactions. 我已经将它们用于异常日志记录,正如您所说的那样,以及性能日志记录......在许多其他事情中,您使用拦截器进行类似的事务处理。

你可以看看使用像Spring.NET或Unity这样的AOP框架,或者看看像PostSharp这样的产品(尽管我从未亲自尝试过PostSharp)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM