- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我面临着一个我无法识别的非常棘手的问题。
我正在运行一个非常大的商业 ASP.Net 应用程序,其中包含数千个对象;它使用内存中的序列化/反序列化和 MemoryStream 来克隆应用程序的状态(保险契约(Contract))并将其传递给其他模块。多年来一直运作良好。现在有时,不是系统地,在序列化中它会抛出异常
Decimal byte array constructor requires an array of length four containing valid decimal bytes.
使用相同的数据运行相同的应用程序,5 次中有 3 次有效。我启用了所有 CLR 异常,Debug - Exceptions - CLR Exception - Enabled,所以我想如果发生错误的初始化/十进制字段赋值,程序应该停止。它不会发生。
我试图在更多基本对象中拆分序列化,但很难尝试识别导致问题的字段。从生产中的工作版本和我从 .Net 3.5 到 .NET 4.0 的这个版本,对 UI 部分而不是业务部分进行了一致的更改。我会耐心地检查所有更改。
当 char *p
写在不该写的地方时,它看起来像老式的 C 问题,只有在序列化过程中检查所有数据时问题才会出现。
在 .Net 的托管环境中是否可能发生这样的事情?该应用程序很大,但我看不到异常的内存增长。调试和跟踪问题的方法是什么?
下面是堆栈跟踪的一部分
[ArgumentException: Decimal byte array constructor requires an array of length four containing valid decimal bytes.]
System.Decimal.OnSerializing(StreamingContext ctx) +260
[SerializationException: Value was either too large or too small for a Decimal.]
System.Decimal.OnSerializing(StreamingContext ctx) +6108865
System.Runtime.Serialization.SerializationEvents.InvokeOnSerializing(Object obj, StreamingContext context) +341
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +448
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) +969
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +1016
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +319
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph) +17
Allianz.Framework.Helpers.BinaryUtilities.SerializeCompressObject(Object obj) in D:\SVN\SUV\branches\SUVKendo\DotNet\Framework\Allianz.Framework.Helpers\BinaryUtilities.cs:98
Allianz.Framework.Session.State.BusinessLayer.BLState.SaveNewState(State state) in
对于冗长的故事和未确定的问题,我深表歉意,我将非常感谢任何帮助。
最佳答案
那是……非常有趣;那时候实际上并不是在读取或写入数据 - 它正在调用序列化前回调,又名 [OnSerializing]
,这里映射到 decimal.OnSerializing
。 that 所做的是尝试对这些位进行完整性检查 - 但看起来 BCL 中只是存在一个错误。这是 4.5 中的实现(咳嗽“反射器”咳嗽):
[OnSerializing]
private void OnSerializing(StreamingContext ctx)
{
try
{
this.SetBits(GetBits(this));
}
catch (ArgumentException exception)
{
throw new SerializationException(Environment.GetResourceString("Overflow_Decimal"), exception);
}
}
GetBits
获取 lo/mid/hi/flags 数组,因此我们可以非常确定传递给 SetBits
的数组是非空且长度正确的.所以要失败,必须失败的部分在 SetBits
中,此处:
private void SetBits(int[] bits)
{
....
int num = bits[3];
if (((num & 0x7f00ffff) == 0) && ((num & 0xff0000) <= 0x1c0000))
{
this.lo = bits[0];
this.mid = bits[1];
this.hi = bits[2];
this.flags = num;
return;
}
throw new ArgumentException(Environment.GetResourceString("Arg_DecBitCtor"));
}
基本上,如果 if
测试通过,我们就会进入,分配值,然后成功退出;如果 if
测试失败,它最终会抛出异常。 bits[3]
是 flags
block ,它包含符号和比例,IIRC。所以这里的问题是:您如何获得带有损坏的 flags
block 的无效 decimal
?
引自MSDN:
The fourth element of the returned array contains the scale factor and sign. It consists of the following parts: Bits 0 to 15, the lower word, are unused and must be zero. Bits 16 to 23 must contain an exponent between 0 and 28, which indicates the power of 10 to divide the integer number. Bits 24 to 30 are unused and must be zero. Bit 31 contains the sign: 0 mean positive, and 1 means negative.
所以要通过这个测试:
不幸的是,我没有找到哪个 decimal
无效的神奇方法...
我能想到的唯一方法是:
GetBits
/new decimal(bits)
- 可能作为 void SanityCheck(this decimal)
方法(可能带有[Conditional("DEBUG")]
之类的)[OnSerializing]
方法添加到您的主域模型中,该方法记录在某处(可能是控制台),以便您可以看到它在爆炸时正在处理的对象关于c# - Binaryformatter 序列化中的十进制字节数组构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18142301/
谁能解释一下原因: (define a (lambda() (cons a #f))) (car (a)) ==> procedure ((car (a))) ==> (procedure . #f)
这是 PyBrain 网站的摘录。我了解大部分正在发生的事情,但是一行让我完全难住了。我以前从未在 python 代码中看到过这样的东西。这是整个循环,对于上下文: for c in [0,
我是gradle / groovy的新手。我想创建将做一些事情的自定义任务。我的第一个问题是任务完成时该如何做?我可以覆盖doFirst / doLast闭包吗?也许我可以重写某些在开始和结束时都会执
我刚刚开始评估 MS 企业库。他们使用以下指令来获取实例: var customerDb = EnterpriseLibraryContainer.Current.GetInstance("C
这是我的 if else Ansible 逻辑.. - name: Check certs exist stat: path=/etc/letsencrypt/live/{{ rootDomain
我正在使用construct 2.8 对一些失传已久的 Pascal 程序创建的一些文件的 header 进行逆向工程。 header 由许多不同的记录组成,其中一些是可选的,我不确定顺序是否固定。
我在将 getchar() 的输入放入 char *arr[] 数组时遇到问题。我这样做的原因是因为输入数据(将是一个带有命令行参数的文件)将存储在一个 char 指针数组中以传递给 execvp 函
通常我们不能约束类型参数 T派生自密封类型(例如 struct 类型)。这将毫无意义,因为只有一种类型适合,因此不需要泛型。所以约束如下: where T : string 或: where T :
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
#include using namespace std; class A { private: int m_i; friend int main(int argc, char cons
这个问题在这里已经有了答案: Are there legitimate uses for JavaScript's "with" statement? (33 个答案) 关闭 9 年前。 我有这个代
在this answer我看到了下一个 Bash 结构。 yes "$(< file.txt)" 什么意思 "$(< file.txt)" ? 我明白了 命令替换 - $(command)用命令的结
if (a == 1) //do something else if (a == 2) //do something else if (a == 3) //do somethi
关于构造的快速简单的问题。 我有以下用于将项目添加到 ListView 的代码。 ListViewItem item = new ListViewItem(); item.Text = file; i
我想使用 std::vector 来控制给定的内存。首先,我很确定这不是好的做法,但好奇心占了上风,无论如何我都想知道如何做到这一点。 我遇到的问题是这样的方法: vector getRow(unsi
下面显示了一段简单的javascript: var mystring = ("random","ignored","text","h") + ("ello world") 这个字符串会生成 hello
在 Java 中,创建对象的标准方法是使用 MyClass name = new MyClass(); 我也经常看到构造 new MyClass() { /*stuff goes in here*/
我正在编写 C++ ndarray 类。我需要动态大小和编译时大小已知的数组(分别分配自由存储和分配堆栈)。我想支持从嵌套的 std::initializer_list 进行初始化。 动态大小的没问题
我正在将一个项目从 Visual Studio 2005 转换为 Visual Studio 2008,并提出了上述结构。 using Castle.Core.Resource; using Cast
我想知道我在这里的想法是否正确,我主要针对接口(interface)进行编程,所以我想知道下面的类是否应该通过 DI 注入(inject),或者我应该自己实例化一个类... 注意:这些服务保存在我的核
我是一名优秀的程序员,十分优秀!