json 从ASP.NET Core 6 Web API控制器返回数据降低性能

kmb7vmvb  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(155)

我们有一个ASP.NET Core 6 Web API项目C#,它最初是从ASP.NET Core 3.1升级而来的。

return new JsonResult(data)

字符串
这是令人难以置信的慢(32秒为120 k行),但做一个

JsonConvert.SerializeObject(data)


只需要3秒钟。
问题在return语句之后,因为

var testResult = new JsonResult(data);
return restResult; //Slow after this. Issue here.


快速到达返回行,但是在返回之后的一些东西增加了30秒。一个简短的调查表明,.NET 6中的一些东西在缓冲区和写入磁盘方面发生了变化,但我不想引导你进入一个潜在的错误的兔子洞。
我们使用Newtonsoft Json(6.0.20),但System.Text.Json(6.0.8)也会出现这个问题。

**更新:**做一个简单的切换到.NET 7解决了这个问题,但.NET 7不是一个长期支持版本。

下面的代码从Neo4j下载所有“边缘”数据,这本身需要大约6秒。6秒,neo4j很好。一切都很好,直到它到达“返回.”部分,它影响每个API上的每个JSON返回,所以它似乎是站点范围的。
我相信这只是在迁移到.NET 6之后才发生的。

/// <summary>
    ///     Returns all edges and required information from the Neo4j database
    /// </summary>
    /// <returns>An array of edges with GeoJson.</returns>
    [Authorize]
    [HttpGet("AllNetwork")]
    public async Task<IActionResult> GetAllMap()
    {
        //checks latest version is in cache.
        int version = neo.GetLatestNetworkStatusVersion();

        if (neo.GetNetworkStatus(version) < NetworkStatus.Uploaded)
        {
            return new JsonResult(CachedNetworkResult.NETWORK_MAINTENANCE());
        }
        Stopwatch stopwatch = Stopwatch.StartNew();

        if (mainMapCache == null || !mainMapCache.Valid(version))
        {
            mainMapCache = null;
            GC.Collect();

            //download new cache if newer is available or no cache loaded
            mainMapCache = new APINetworkResultCache(version)
            {
                Result = await neo.GetMapAllAsync() //Array []
            };
        }
        else
        {
            mainMapCache.CacheUsed = true;
        }

        var res = CachedNetworkResult.SUCCESS(mainMapCache);
        mainMapCache.DownloadTime = stopwatch.ElapsedMilliseconds;
        Debug.WriteLine($"Retrieved network in {mainMapCache.DownloadTime:N0}ms");

        return Json(res); //ISSUE HERE
    }


我试过了:

  • return new JsonResult(res);
  • https://github.com/dotnet/aspnetcore/issues/40579和https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.mvcnewtonsoftjsonoptions.outputformattermemorybufferthreshold?view=aspnetcore-6.0#microsoft-aspnetcore-mvc-mvcnewtonsoftjsonoptions-outputformattermemorybufferthreshold将“OutputInterMemoryBufferThreshold”设置为30 MB和300 MB
  • 删除pwtc/await并使其同步。
  • MvcOptions. SuppressOutputBuffering = true
  • https://purple.telstra.com/blog/how-we-sped-up-an-aspnet-core-endpoint-from-20-seconds-down-to-4-seconds的两个选项
  • 通过Postman检索结果(同时)。23.7MB文件
  • 不使用Newtonsoft Json,使用默认的.NET 7可以完美地工作,并在1秒内返回数据(没有其他修改)。
  • 返回new JsonResult,返回Json,返回Ok,返回Content。

这是引用Newtonsoft JSON的startup.cs文件的一部分:

services.AddMvc()
    //.AddJsonOptions(options =>
    //{
    //    options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull;
    //    options.JsonSerializerOptions.PropertyNameCaseInsensitive = false;
    //})
    .AddMvcOptions(options =>
    {
        options.EnableEndpointRouting = false;
    })
    .AddNewtonsoftJson();

// Adds a default in-memory implementation of IDistributedCache.
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromHours(8);
    options.Cookie.HttpOnly = false;
    options.Cookie.IsEssential = true;
});

services.AddControllers().AddNewtonsoftJson();
services.AddControllersWithViews().AddNewtonsoftJson();
services.AddRazorPages().AddNewtonsoftJson();

kwvwclae

kwvwclae1#

你的问题没有足够的细节来建议其他事情。但是如果你对

JsonConvert.SerializeObject(data)

字符串
你可以尝试

var json = JsonConvert.SerializeObject(data);
return Content(json, "application/json");


如果它不工作,那么你的问题就不在序列化上,而是在服务器和客户端之间的路上。

相关问题