在C#中缓存异常实例是一个好习惯吗

Fab*_*Fab 3 c# multithreading caching exception-handling exception

我正试图在这个问题上找到答案,即:

以下代码是一个好习惯吗?
我应该尝试在任何可能的地方重现它吗?如果没有,为什么?

public class ExceptionHelper
{
    private static readonly HttpException _errorReadingRequest = new HttpException(500, "Error reading request. Buffer is empty.");
    public static Exception ErrorReadingRequest { get { return _errorReadingRequest; } }
}

public class ExceptionThrower
{
    public static void ThrowCached1()
    {
        throw ExceptionHelper.ErrorReadingRequest;
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我试图在几个地方放入缓存的实例,它似乎保留了来自MSDN的堆栈跟踪,

堆栈跟踪从抛出异常的语句开始,并以捕获异常的catch语句结束.在决定将throw语句放在何处时,请注意这一事实.

我理解为" 它将堆栈跟踪存储在抛出,而不是创建 ".但是,我想知道当多个线程尝试抛出相同的缓存异常实例时是否会出现问题.

在同一个MDSN页面上,他们正在使用一个辅助函数,它似乎在框架中,他们正在做同样的事情:辅助函数,它重新创建异常并抛出.

注意:我知道这不是常见的情况,因为大多数情况下,您希望将特定消息存储在异常中,以便更容易理解正在发生的事情.

也许问题刚好是关键字线程安全的没有

语境:

我偶然发现了这种代码,同时代码审查了一些性能敏感的应用程序代码.目标是在启动期间创建最大的实例,然后在执行期间从不(或几乎从不)实例,以限制GC性能影响(特别是因为堆碎片与GCHandle事物发生).我对这段代码感觉不好,但需要事实来支持我的重构.

小智 9

通常,有一个缓存的异常是没有意义的.创建一个对象很快.例外情况很少见 - 捕捉它们有一些开销,就像投掷它们一样.除了以下情况之外,完全没有从"一个例外来统治所有人"中获得任何好处.

  • 线程问题
  • 更复杂的代码
  • 完全忽略了我在过去20年中看到的编码标准.

如果这些事情中的任何一个是你的目标 - 那就去吧.

也许问题只是抛出关键字线程安全与否?

throw关键字是线程安全的 - 您可以同时抛出多个线程.使用相同的异常会让你遇到麻烦,但这不是因为抛出KEYWORD不是线程安全的,而是因为你通过传入相同的数据对象而恶意侵犯线程安全.