从应用程序代码抛出OutOfMemoryException是好的设计
本文关键字:OutOfMemoryException 应用程序 代码 | 更新日期: 2023-09-27 18:14:56
我记得我在某处读到过,从用户代码中抛出任何System.SystemException
派生的异常是一种不好的做法,因为用户代码应该只抛出应用程序异常。
我们有一个使用GPU的本地库。它可能会返回一个错误代码,表明我们的GPU内存不足。我们想把这个错误代码转换成。net异常。
这是我能想到的可能的例外:
-
System.OutOfMemoryException
-
System.InvalidOperationException
与适当的文字 - 自定义异常(基于InvalidOperationException)
哪一个是最好的,为什么?
扔System.OutOfMemoryException
不是理想的选择。使用您的库的程序员可能会对System.OutOfMemoryException
做出反应,从内存中清除一些不重要的对象,然后再次尝试。然而,在你的情况下,它是GPU内存,而不是系统内存,所以他们的尝试将没有机会工作。
如果用户可以选择直接或间接地从GPU内存中卸载东西,自定义异常方法(第三条)提供了最干净的选择。如果他们完全无法控制它,即异常基本上是一个"你死了"的消息,那么System.InvalidOperationException
也是一个不错的选择。
引发OutOfMemoryException
是最糟糕的选择。这样做的原因是,这种异常在一般情况下几乎不可能恢复,对于客户端来说,很难确定是系统内存耗尽还是您只是滥用了这种异常类型,特别是因为客户端不会期望这种行为。
引发InvalidOperationException
是一件更好的事情,因为客户端将能够处理这个问题(通过将计算卸载到其他地方或在CPU中执行所需的东西,可能使用不同的库)。但是,如果异常是InvalidOperationException
,则该异常类型很可能也被其他库或BCL使用。因此,客户端必须通过解析错误消息来响应此异常,这是不可靠的。
InvalidOperationException
继承,而是直接从Exception
继承。
抛出的异常应该具有信息性,因此让我们查找候选异常:
System.OutOfMemoryException
https://msdn.microsoft.com/en-us/library/system.outofmemoryexception (v = vs.110) . aspx
OutOfMemoryException异常有两个主要原因:
- 你正在尝试扩展StringBuilder对象,超出其StringBuilder定义的长度。MaxCapacity财产。
公共语言运行库无法分配足够的连续内存来成功执行操作。这个例外可以是的任何属性赋值或方法调用都会抛出内存分配。有关事故原因的更多信息OutOfMemoryException异常,参见"Out of Memory"不参考物理内存。
读过这篇文章后,我认为System.OutOfMemoryException
是一个非常错误的候选人:它误导了,因为在你的情况下问题是与GPU而不是与RAM。
第二个候选者是
System.InvalidOperationException
https://msdn.microsoft.com/en-us/library/system.invalidoperationexception (v = vs.110) . aspx
方法调用无效时引发的异常对象的当前状态
小姐;状态为OK,是GPU内存不足。
所以我建议实现你自己的自定义异常,然而,不基于System.InvalidOperationException
,而是基于Exception
通过抽象GpuException
:
Exception
GpuException // Abstract (wrong GPU, lack of support etc.)
GpuOutOfMemoryException // Not enough memory on board