我有多个属性类,它们需要访问HttpContent
(位于HttpActionContext
的{{1}}中)中的数据,但是我在确定最佳方法时遇到了问题做吧。我考虑过在HttpRequstMessage
上使用ReadAsStringAsync
方法,但是似乎我需要访问HttpContent
才能首先将位置设置为0。
幼稚的方式似乎只是用Stream
语句将StreamReader
包裹在基本流中,如下所示:
using
这对于执行的第一个属性效果很好,但是随后执行的每个后续属性都会因public override void OnActionExecuting(HttpActionContext actionContext)
{
string rawJson;
using (StreamReader streamReader = new StreamReader(actionContext.Request.Content.ReadAsStreamAsync().Result))
{
streamReader.BaseStream.Position = 0;
rawJson = streamReader.ReadToEnd();
}
// etc
}
而被抛出异常。
actionContext.Request.Content.ReadAsStreamAsync()
包裹在基本流中,切勿丢弃。StreamReader
这对每个属性都适用,但是我担心我可能由于不处理public override void OnActionExecuting(HttpActionContext actionContext)
{
StreamReader streamReader = new StreamReader(actionContext.Request.Content.ReadAsStreamAsync().Result);
streamReader.BaseStream.Position = 0;
string rawJson = streamReader.ReadToEnd();
// etc
}
而泄漏了内存。
StreamReader
并用MemoryStream
包装。StreamReader
这对每个属性都适用,但是大量代码,可能效率不高。
public override void OnActionExecuting(HttpActionContext actionContext)
{
MemoryStream memoryStream = new MemoryStream();
Stream s = actionContext.Request.Content.ReadAsStreamAsync().Result;
s.Position = 0;
s.CopyTo(memoryStream);
string rawJson;
using (StreamReader streamReader = new StreamReader(memoryStream))
{
streamReader.BaseStream.Position = 0;
rawJson = streamReader.ReadToEnd();
}
// etc
}
。ReadAsStringAsync
这对每个属性都适用,但是效率可能较低。
那么,有没有一种最佳的方式来做到这一点而又不会泄漏内存?
答案 0 :(得分:0)
使用使流保持开放状态的流读取器-由于您不拥有流的所有权,因此它仍属于HTTP操作内容的范围。
public StreamReader (System.IO.Stream stream, System.Text.Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen);
Constructor with the option to leave the stream open
由于可能出现死锁,在同步上下文中也使用.Result来完成异步调用是有风险的。尝试将您的方法重构为异步方法。