我有一个查询数据库并返回JSON的WCF4 REST服务。尽管我很难返回字符串,但有些用户希望做出非常大的查询。例如,我需要返回一个500M JSON字符串(所有数据都是ASCII文本),但是当我尝试从.NET的本机UTF-16转换字符串时,我遇到了OutOfMemoryException。这是我正在做的一个简洁的样本。将大字符串转换为UTF-8
[WebInvoke(UriTemplate="/RunQuery", ResponseFormat=WebMessageFormat.Json)]
public Stream RunQuery() {
// Perform query and return serialized json string (~500 million ASCII characters)
string json = DoQuery(HttpContext.Current.Request.Form);
// Set output charset
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
// Convert UTF-16 string to UTF-8 (OutOfMemoryException)
byte jsonBytes[] = System.Text.Encoding.UTF8.GetBytes(json)
// Send UTF-8 string, without BOM
return new MemoryStream(jsonBytes);
}
如果我把JSON低于200M左右,它才有效。当它运行时,我看到IIS进程的内存使用量逐渐增加,然后爆炸到2.8G,并在此时死亡。堆栈跟踪报告它发生在System.String.ToCharArray。我尝试了将字符串分块来构建字节数组的变体,但似乎没有任何工作。任何想法如何我可以发送这些数据而不用炸毁?
500M JSON?哎哟。难道你不能将数据分成页面吗? – 2012-01-27 20:33:40
只是一个猜测:你可以尝试写入响应数据到一个临时文件块,然后返回一个打开的流为临时文件? (最好你应该重新构造DoQuery(),以便它支持将其结果写入输出流而不是返回流。如果不需要,你实际上不应该缓存整个兆字节的数据。) – millimoose 2012-01-27 20:34:53
或将数据流传回客户端.... – Polity 2012-01-27 20:35:39