.net核心Web应用程序-所有这些内存都在使用什么?小可枚举vs大可枚举vs流响应

时间:2018-11-17 08:05:42

标签: c# memory web-applications .net-core

当Web应用程序发送大响应时,我试图了解服务器的内存使用情况。

我在磁盘上生成了一个约100 MB的文本文件,只是作为一些要发送的数据。请注意,我实际上可能并不想发回文件(即,我实际上并不总是希望使用FileStreamResult)。该文件只是我实验的数据源。

我公开了三个不同的get请求。

  • Small返回一个很小的ActionResult<IEnumerable<string>>。这是我的控制权。
  • BigActionResult<IEnumerable<string>>的形式返回文件内容。
  • Stream实现自定义IActionResult,并将行直接写到Response.Body。

运行Web应用程序时,我在Visual Studio诊断工具中看到以下结果:

  • 启动时,进程内存为87兆。
  • 命中/small网址->仍然〜87兆。
  • 命中/big网址->迅速跳至〜120兆。
  • 命中/stream网址->慢慢升至〜110兆。

据我了解,红est的响应缓冲区为64kb,我认为我已经正确装饰了禁用响应缓存的方法。那么,是什么导致服务器的内存消耗增加太多,我能做些什么来确保服务器不必使用所有这些额外的内存?我希望我可以真正地将结果“流式传输”到客户端,而不必让服务器内存使用量如此之高。

此外,我对ASP Net Core MVC Web应用程序API还是很陌生(真是太嘴了!),因此欢迎其他提示。

using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

namespace WebApplication1.Controllers
{
    public static class EnumerableFile
    {
        public static IEnumerable<string> Lines
        {
            get
            {
                using (var sr = new StreamReader(@"g:\data.dat"))
                {
                    string s = null;
                    while ((s = sr.ReadLine()) != null)
                    {
                        yield return s;
                    }
                }
            }
        }        
    }

    public class StreamResult : IActionResult
    {
        public Task ExecuteResultAsync(ActionContext context)
        {
            return Task.Run(
                () =>
                {
                    using (var sr = new StreamReader(@"g:\data.dat"))
                    {
                        string s = null;
                        while ((s = sr.ReadLine()) != null)
                        {
                            context.HttpContext.Response.Body.Write(System.Text.Encoding.UTF8.GetBytes(s));
                        }
                    }
                }
            );
        }
    }

    [ApiController]
    public class ValuesController : ControllerBase
    {
        [Route("api/[controller]/small")]
        [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
        public ActionResult<IEnumerable<string>> Small()
        {
            return new string[] { "value1", "value2" };
        }

        [Route("api/[controller]/big")]
        [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
        public ActionResult<IEnumerable<string>> Big()
        {
            return Ok(EnumerableFile.Lines);
        }

        [Route("api/[controller]/stream")]
        [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
        public IActionResult Stream()
        {
            return new StreamResult();
        }
    }
}

0 个答案:

没有答案