我有一些我无法弄清楚的奇怪行为。
我正在使用 WCF 服务将文件保存到特定的数据库表中。 WCF 服务有一个单一的方法,它接受一个 JSON 字符串作为参数。本例中的 JSON 是一个序列化命令,其中包含 List<FileData>
在其他属性中。 WCF 服务反序列化 JSON 并运行 CommandHandler
对于这个特定的命令。
一位最终用户在尝试上传大小为 52 MB 的文件时遇到了错误。 WCF 服务返回了 404 错误。
我能够在 Visual Studio 中重现这一点。根据此更改配置文件后 article , 404 消失了。
但是现在出现了一个新的异常:虽然命令在客户端成功序列化,并由 WCF 成功处理,但反序列化抛出一个 OutOfMemoryException
.这是堆栈跟踪的顶部:
at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired) at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append) at Newtonsoft.Json.JsonTextReader.ReadStringIntoBuffer(Char quote) at Newtonsoft.Json.JsonTextReader.ParseString(Char quote) at Newtonsoft.Json.JsonTextReader.ParseValue() at Newtonsoft.Json.JsonTextReader.ReadInternal() at Newtonsoft.Json.JsonReader.ReadAsBytesInternal() at Newtonsoft.Json.JsonTextReader.ReadAsBytes() at 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 中测试上传大文件,而它在生产中工作。请注意,我还尝试在 Release模式下以 Debug模式运行。
一些细节:
- 使用 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
最佳答案
我通过将 byte[] bytes = new byte[80000000];
更改为 byte[] bytes = new byte[,在单元测试中重现了
并循环运行(2 次)。测试运行器是 32 位的。OutOfMemoryException
52000000];
回到 IIS Express - 我认为您使用的是 32 位版本。您可以在
更改此设置Tools | Options | Projects and Solutions | Web Projects | Use the 64 bit version of IIS Express
关于c# - Json.Net 仅在 Visual Studio 中抛出 OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37642357/