读取 Post 响应时 C# OutOfMemory 异常

C# OutOfMemory Exception when reading Post Response

我目前正在开发一个简单的应用程序,它利用 JSON 对象到 POST 到 API 并获取响应数据。但是,当我 运行 POST 方法时,POST 响应太大以至于我遇到了 OutOfMemory 异常。

我目前正在为进程使用 WebClient 和 CookieContainer:

string jsonObject ="...."; //Example JSON string - It's very small

using (var client = new WebClient())
{
     var auth = new NameValueCollection();
       values["username"] = "username";
       values["password"] = "password";

     client.uploadValues(endpoint,auth);

     // This is causing the OutOfMemory Exception
     var response = client.uploadString(endpoint, jsonObject);

}

我已经调查了这个问题,并将 属性 AllowStreamBuffering 设置为 false。

 client.AllowStreamBuffering() = false;

但是,我还是遇到了这个问题,不知道如何控制POST响应。


更新:2017 年 7 月 5 日

多亏了@Tim 的建议,我已经转移到响应流,但是我遇到了有关实际响应的问题。使用 POST 方法将 JSON(作为字符串)写入终点后,脚本在尝试读取响应时卡住了。

    String endPoint = @"http://example.com/v1/api/";
    String json = @"....";

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
    request.Method = "POST";
    request.KeepAlive = false;
    request.AllowReadStreamBuffering = false;

    /* Pretend this middle part does the Authorization with username and password. */
    /* I have actually authenticated using the above method, and passed a key to the request */

    //This part POST the JSON to the API
    using (StreamWriter writeStream = new StreamWriter(request.GetRequestStream()))
        {
            writeStream.Write(json);
            writeStream.Flush();
            writeStream.Close();  
        }

    //This bottom part opens up a console, but never reads or loads the data
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream());

我想知道 JSON 是否可能没有编码。


(旁注:我看过将响应逐行写入文件,但正是响应导致了问题——http://cc.davelozinski.com/c-sharp/fastest-way-to-read-text-files

我能够解决我自己的问题。对于 header,我忘记编码 JSON,并为 API 正确设置 content-type。

这里的代码与上面的流完全相同,但更新了 header 和 bufferedStream 以提高处理数据和内存的效率。

String endPoint = @"http://example.com/v1/api/";
String json = @"....";//Example JSON string

Byte[] jsonData = Encoding.UTF8.GetBytes(json);

StreamWriter file = new StreamWriter(@"File Location");

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Method = "POST";
request.ContentType = "text/plain";
request.KeepAlive = false;
request.AllowReadStreamBuffering = false;
request.ContentLength = jsonData.Length;

/* Pretend this middle part does the Authorization with username and password. */
/* I have actually authenticated using the above method, and passed a key to the request */

 //This part POST the JSON to the API
 Stream writeStream = request.GetRequestStream();
 writeStream.Write(jsonData, 0, jsonData.Length);

 //This conducts the reading/writing into the file
 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 using (Stream receivedStream = response.GetResponseStream())
 using (BufferedStream bs = new BufferedStream(receivedStream))
 using (StreamReader sr = new StreamReader(bs))
 {
       String s;
       while ((s = sr.ReadLine()) != null)
       {
            file.WriteLine(s);
        }

 }

这里的很多方法来自 Dave Lozinski 的博客 post 关于内存处理、流读取和流写入(尽管他使用文件而不是流)。通过上面的 post 寻求帮助非常有用。