【发布时间】:2016-06-05 13:16:48
【问题描述】:
我有一些奇怪的行为,我无法弄清楚。
我正在使用 WCF 服务将文件保存到某个数据库表。 WCF 服务有一个将 JSON 字符串作为参数的方法。在这种情况下,JSON 是一个序列化命令,其中包含 List<FileData> 以及其他属性。 WCF 服务反序列化 JSON 并为此特定命令运行 CommandHandler。
最终用户在尝试上传大小为 52 MB 的文件时遇到了错误。 WCF 服务返回 404 错误。
我能够在 Visual Studio 中重现这一点。按照这个article修改配置文件后,404就消失了。
但是现在出现了一个新的异常:当命令成功序列化客户端,被 WCF 成功处理时,反序列化抛出一个OutOfMemoryException。这是堆栈跟踪的顶部:
在 Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired) 在 Newtonsoft.Json.JsonTextReader.ReadData(布尔附加) 在 Newtonsoft.Json.JsonTextReader.ReadStringIntoBuffer(字符引用) 在 Newtonsoft.Json.JsonTextReader.ParseString(字符引用) 在 Newtonsoft.Json.JsonTextReader.ParseValue() 在 Newtonsoft.Json.JsonTextReader.ReadInternal() 在 Newtonsoft.Json.JsonReader.ReadAsBytesInternal() 在 Newtonsoft.Json.JsonTextReader.ReadAsBytes() 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter)
我写了一个单元测试来证明这个错误。但无论如何,这个测试通过了,换句话说,没有OutOfMemoryException被抛出。
为了完整性而进行的测试:
[TestMethod]
public void LoadBigFile_SerializeDeserialize_DoesntThrowOutOfMemoryException()
{
// Arrange
byte[] bytes = new byte[80000000];
Random r = new Random(23);
r.NextBytes(bytes);
var command = new SomeCommand(new List<FileData>
{
new FileData(
fileFullName: @"D:\SomePdfFile.pdf",
modifyDate: DateTime.MaxValue,
data: bytes
)
});
var data = JsonConvert.SerializeObject(command);
// Act
var deserializedCommand =
JsonConvert.DeserializeObject<SomeCommand>(data);
// Assert
Assert.AreEqual(bytes.Length, deserializedCommand.Files.First().Data.Length);
}
所以,我抓住机会更改了生产环境中的配置文件并尝试上传相同的文件。那就行了!!!没有OutOfMemoryException!
现在我的问题是,为什么OutOfMemoryException 只发生在 Visual Studio 中,而同一 VS 实例中的单元测试却没有?感觉有点奇怪,我无法在 Visual Studio 中测试上传大文件,而它在生产中工作。请注意,我还尝试像在发布模式下一样在调试中运行。
一些细节:
- 使用 Json.Net 7.0.1
- Visual Studio 2015,更新 2
- WCF 在本地托管在 IIS Express 中,在生产环境中托管 IIS
- Windows 10 最新版本 64 位
- 生产服务器 Windows server 2008 R2 64 位
- .Net Framework 4.5.2
【问题讨论】:
-
您的本地开发机器是 32 位还是 64 位?这与部署服务器不同吗?您的配置是“任何 CPU”吗?
-
@mellamokb:我的开发机器和服务器都是 64 位的。
标签: c# visual-studio-2015 json.net deserialization