用于记录目的的 C# 类库中未处理的异常
我是软件开发新手,也是 stackoverflow 新手,所以请对我宽容点。
背景:我正在开发一个 C# 类库,用于处理第三方应用程序通过 tcp/ip (使用异步套接字)发送的 xml 消息。我正在使用 com-interop 以便将类库公开给 Vb6 应用程序。当 C# 库处理通过套接字接收到的 xml 时,它会引发消费 vb6 应用程序订阅的各种事件(这样,当我们最终在 .Net 中重写整个应用程序时,我们就已经完成了这个组件)。
问题:我想捕获所有未处理的异常,仅用于记录目的。在 winforms 应用程序中,您可以将事件连接到 AppDomain.CurrentDomain.UnhandledException 和 Application.ThreadException。是否没有办法类似地获取异常数据以将信息记录在类库中?
要点:
我并不是试图从这些异常中恢复,而是只是记录它们并让异常传播并在需要时使应用程序崩溃。
我正在尽最大努力在本地捕获所有可能发生的特定异常。因此,我的目的是只记录真正意外的异常。
- 我知道有些人会说这是一个糟糕的设计模式。我应该让调用者处理这些异常。问题是 vb6 应用程序没有像我希望的那样强大的错误处理功能。主要是,我想记录堆栈跟踪,以便如果 vb6 应用程序由于我的 dll 而崩溃,我可以查看日志,以便收到有关可能需要更改的 C# 代码的潜在区域的警报。
有人可以给我一些指导吗?到目前为止,我发现的最佳选择似乎是在每个公共方法中放置一个通用的 try catch 块,记录异常,然后抛出它。这似乎不太理想:
public void SomeMethod()
{
try
{
// try something here...
}
catch (Exception ex)
{
Log(ex);
throw;
}
}
这不仅看起来是一个糟糕的设计,而且我不知道如果其中一个异步回调在与调用该方法的线程不同的线程上引发异常会发生什么。这个通用的 try/catch 块还会捕获这样的异常吗?
感谢您的任何帮助。
编辑:我最初将@Eric J.的答案标记为正确,但在尝试实现该解决方案后,我发现它不能很好地与我所在的套接字类的异步回调配合使用使用。一旦使用线程池线程来触发异步回调,我似乎无法捕获堆栈中稍后发生的任何异常。我需要使用 AOP 框架,还是有其他方法来捕获这些异常?
I am new to software development and also new to stackoverflow, so go easy on me.
BACKGROUND: I am developing a C# class library that processes xml messages sent by a third party application over tcp/ip (using Async sockets). I am using com-interop in order to expose the class library to a Vb6 application. 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).
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. 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. 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.
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. 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?
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. 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您的库入口点集有限,请考虑按照您的建议进行操作 - 使用 .NET 包装器类或包装器库来执行实际的互操作并捕获/记录该包装器类中的异常。返回调用 VB6 库知道如何处理的异常或错误代码(是否重新引发异常取决于 VB6 代码可以处理的内容)。
CrazyDart 建议 IOC,这是一个有趣且有效的替代方案,但最初也增加了复杂性和学习曲线。当然也可以看看国际奥委会并认为这是一种可能性。
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. 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).
CrazyDart suggests IOC, which is an interesting and valid alternative but also adds complexity and learning curve initially. Certainly have a look at IOC as well and concider it as a possibility.
您可以使用温莎城堡和拦截器来实现此目的。这是在项目中使用 IOC 的一个很好的理由。
http://blog.andreloker .de/post/2009/02/20/Simple-AOP-integrating-interceptors-into-Windsor.aspx
我已经将它们用于异常日志记录,正如您所说,以及性能日志记录......在许多其他事情中,您使用拦截器来进行类似的事务。
You could use Castle Windsor and an interceptor for this. Its a good reason to use IOC on projects.
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)。
You could either look at using an AOP framework like Spring.NET or Unity, or alternatively look at a product such as PostSharp (though I have never personally tried PostSharp).