ASP.NET Core中重新触发ViewComponent时出现同步操作禁用错误及net::ERR_HTTP2_PROTOCOL_ERROR 200问题求助
ASP.NET Core中重新触发ViewComponent时出现同步操作禁用错误及net::ERR_HTTP2_PROTOCOL_ERROR 200问题求助
大家好,我最近遇到了一个非常棘手的问题,折腾了好几天都没找到根因,想请各位大佬帮忙分析下:
我在项目页面里用了DataTablesJS表格,为了避免数据量过大导致页面卡顿,混合了客户端排序/过滤和服务端重渲染的方案。页面首次加载的时候一切都正常,但当我重新触发ViewComponent进行数据刷新时,就会出现两个异常问题:
- 浏览器控制台抛出
net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK)错误 - 后端宿主的堆栈跟踪里出现同步操作禁用的异常:
System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
相关代码片段
控制器中调用ViewComponent的方法
public async Task<IActionResult> ReloadInventoryViewComponent(InventoryModel inventoryModel) { // 这里会先处理并填充selectedFilters等参数 return ViewComponent("Inventory", new { ProductionOrderNumber = inventoryModel.ProductionOrderNumber, CurrentUser = inventoryModel.CurrentUser, SelectedFilters = selectedFilters, FilterOptions = inventoryModel.FilterOptions }); }
ViewComponent的Invoke方法
public async Task<IViewComponentResult> InvokeAsync(string ProductionOrderNumber, string CurrentUser, List<ODataFilter> SelectedFilters, FilterOptions FilterOptions) { // 这里的业务逻辑都能正常执行,没有任何问题 return View(model); // 这一步单步调试时是正常的,但再往下走就会触发错误 }
奇怪的现象
- 明明所有相关方法都声明了
async,但却抛出了同步/异步不兼容的错误 - 当ViewComponent返回的模型中,DataTablesJS用到的数据集少于20条左右时,页面能完全正常渲染,没有任何错误。这让我更加确定问题和异步/同步有关——因为数据少的时候执行速度快,就不会触发这个错误
我已经做过的排查尝试
- 反复检查了所有相关方法的签名,确保都是异步声明
- 尝试开启了
AllowSynchronousIO配置,但问题依旧存在 - 搜了很多关于
net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK)的解决方案,但我觉得核心问题应该是那个同步操作的异常,所以更关注这个根因
完整的异常堆栈跟踪
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1] An unhandled exception has occurred while executing the request. System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead. at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.Stream.Write(ReadOnlySpan`1 buffer) at Microsoft.WebTools.BrowserLink.Net.WebSocketScriptInjection.TryInjectBrowserLinkScript(Stream baseStream, ReadOnlySpan`1 buffer) at Microsoft.WebTools.BrowserLink.Net.ResponseStreamWrapper.Write(Byte[] buffer, Int32 offset, Int32 count) at Microsoft.AspNetCore.WebUtilities.HttpResponseStreamWriter.Write(String value) at Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers.ViewBuffer.WriteToAsync(TextWriter writer, HtmlEncoder encoder) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewComponentResultExecutor.ExecuteAsync(ActionContext context, ViewComponentResult result) at Microsoft.AspNetCore.Mvc.ViewFeatures.ViewComponentResultExecutor.ExecuteAsync(ActionContext context, ViewComponentResult result) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|22_0(ResourceInvoker invoker, IActionResult result) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|28_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Author...
有没有大佬遇到过类似的情况?或者能指出我哪里可能忽略了同步操作的问题?
内容来源于stack exchange
相关产品推荐
相关产品推荐

