C# 使用IViewComponentThelper将ViewComponent转换为HTML字符串时出现线程问题

C# 使用IViewComponentThelper将ViewComponent转换为HTML字符串时出现线程问题,c#,multithreading,asp.net-core,asp.net-core-viewcomponent,C#,Multithreading,Asp.net Core,Asp.net Core Viewcomponent,我正在尝试以多线程的方式使用。但它抛出:((请参阅文章底部的完整异常) 我不知道为什么 以下是我的设置:(为简洁起见简化) 控制器: 公共异步任务Get() { var pdfStream=await _pdfService.GenerateAsync(); 返回文件(pdfStream,“应用程序/pdf”); } PDF服务: 公共类PDF服务 { 专用只读PDFSDKu PdfSDK; 公共建造商(PdfSDK PdfSDK) { _pdfSDK=pdfSDK; } 公共异步任务Gene

我正在尝试以多线程的方式使用。但它抛出:((请参阅文章底部的完整异常)

我不知道为什么

以下是我的设置:(为简洁起见简化)

控制器:

公共异步任务Get() { var pdfStream=await _pdfService.GenerateAsync(); 返回文件(pdfStream,“应用程序/pdf”); } PDF服务:

公共类PDF服务
{
专用只读PDFSDKu PdfSDK;
公共建造商(PdfSDK PdfSDK)
{
_pdfSDK=pdfSDK;
}
公共异步任务GenerateAsync()
{
List tasks=wait_context.Foos.Select(x=>doworksync(x));
var pdfs=等待任务.WhenAll(任务);
var mergedPdf=_pdfSDK.MergePdfs(pdf);
返回mergedPdf.Stream;
}
专用异步任务DoWorkAsync(Foo-Foo)
{
var html=await_renderViewComponentService.RenderViewComponentAsStringAsync(foo);
var document=await_pdfSDK.htmltodocumentsync(html);
归还文件;
}
}
PdfSDK:

公共类PdfSDK
{
公共异步任务HtmlToDocumentAsync(字符串html)
{
使用var pdfEngine=new pdfEngine();
var pdf=await pdfEngine.htmlapdfasync(html);
返回pdf;
}
公共PDF文档合并PDF(参数PDF文档[]PDF)
{
var pdf=PdfDocument.Merge(pdf);
返回pdf;
}
}
MyViewComponent:

公共类MyViewComponent:ViewComponent { 公共IViewComponentResult调用(Foo args) { 返回视图(args); } } Default.cshtml

@model Foo

<h1>Hello from @Foo.Id<h1>
@model Foo
你好,来自@Foo.Id
RenderViewComponentService:

公共类RenderViewComponentService
{
私有只读服务器ViceProvider\u服务提供商;
私有只读ITempDataProvider _tempDataProvider;
私有只读IViewComponentHelper _viewComponentHelper;
公共渲染视图组件服务(
IServiceProvider服务提供商,
ITempDataProvider tempDataProvider,
IViewComponentHelper视图组件帮助器
)
{
_服务提供者=服务提供者;
_tempDataProvider=tempDataProvider;
_viewComponentHelper=viewComponentHelper;
}
公共异步任务RenderViewComponentAstringAsync(对象参数)
其中TViewComponent:ViewComponent
{
var viewContext=GetFakeViewContext();
(_viewComponentHelper作为IViewContextAware)。上下文化(viewContext);
//这似乎在TViewComponent中调用了InvokeAsync,但如果实现了它,它也会(同步地)调用Invoke
//看https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1#执行同步工作
var htmlContent=await _viewComponentHelper.InvokeAsync(args);//这里抛出异常!
使用var stringWriter=new stringWriter();
htmlContent.WriteTo(stringWriter,HtmlEncoder.Default);
var html=stringWriter.ToString();
返回html;
}
私有ViewContext GetFakeViewContext(ActionContext ActionContext=null,TextWriter=null)
{
actionContext???=GetFakeActionContext();
var viewData=new ViewDataDictionary(new EmptyModelMetadataProvider(),new ModelStateDictionary());
var tempData=新的TempDataDictionary(actionContext.HttpContext,_tempDataProvider);
var viewContext=新的viewContext(
行动背景,
NullView.Instance,
viewData,
tempData,
writer??TextWriter.Null,
新的HtmlHelpOptions());
返回viewContext;
}
私有ActionContext GetFakeActionContext()
{
var httpContext=新的DefaultHttpContext
{
RequestServices=\u serviceProvider,
};
var routeData=新routeData();
var actionDescriptor=新的actionDescriptor();
返回新的ActionContext(httpContext、RoutedData、actionDescriptor);
}
私有类NullView:IView
{
公共静态只读NullView实例=新建NullView();
公共字符串路径=>string.Empty;
公共任务RenderAsync(ViewContext上下文)
{
如果(context==null){抛出新的ArgumentNullException(nameof(context));}
返回Task.CompletedTask;
}
}
}
例外情况:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Items()
   at Microsoft.AspNetCore.Mvc.Routing.UrlHelperFactory.GetUrlHelper(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.<>c__DisplayClass4_0.<.ctor>b__0(ViewContext context)
   at Microsoft.Extensions.Internal.PropertyActivator`1.Activate(Object instance, TContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorPagePropertyActivator.Activate(Object page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.Activate(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)        
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.ViewViewComponentResult.ExecuteAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentInvoker.InvokeAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentHelper.InvokeCoreAsync(ViewComponentDescriptor descriptor, Object arguments)
   at MyProject.Services.RenderViewComponentService.RenderViewComponentToStringAsync[TViewComponent](Object args) in MyProject\Services\RenderViewComponentService.cs:line ??
   at MyProject.Services.PdfService.DoWorkAsync(Foo foo) in MyProject\Services\PdfService.cs:line ??
   at MyProject.Services.PdfService.GenerateAsync() in MyProject\Services\PdfService.cs:line ??
   at MyProject.Controllers.MyController.Get() in MyProject\Controllers\MyController.cs:line ??
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker 
invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_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|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.HeaderPropagation.HeaderPropagationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
fail:Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
执行请求时发生未经处理的异常。
System.NullReferenceException:对象引用未设置为对象的实例。
在Microsoft.AspNetCore.Http.DefaultHttpContext.get_Items()上
位于Microsoft.AspNetCore.Mvc.Routing.UrlHelperFactory.GetUrlHelper(ActionContext上下文)
在Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.c__显示Class4_0.b__0(ViewContext上下文)
位于Microsoft.Extensions.Internal.PropertyActivator`1.Activate(对象实例,TContext上下文)
在Microsoft.AspNetCore.Mvc.Razor.RazorPagePropertyActivator.Activate(对象页,ViewContext上下文)中
在Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.Activate(IRazorPage页面,ViewContext上下文)中
位于Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAncync(IRazorPage页面,ViewContext上下文)
位于Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage页面、ViewContext上下文、布尔invokeViewStarts)
位于Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext上下文)
位于Microsoft.AspNetCore.Mvc.ViewComponents.ViewComponentResult.ExecuteAsync(ViewComponentContext上下文)
在Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentVoker.InvokeAsync(ViewComponentContext上下文)中
位于Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentHelper.InvokeCoreAsync(ViewComponentDescriptor描述符,对象参数)
在MyProject.Services.RenderViewComponent上
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.AspNetCore.Http.DefaultHttpContext.get_Items()
   at Microsoft.AspNetCore.Mvc.Routing.UrlHelperFactory.GetUrlHelper(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.<>c__DisplayClass4_0.<.ctor>b__0(ViewContext context)
   at Microsoft.Extensions.Internal.PropertyActivator`1.Activate(Object instance, TContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorPagePropertyActivator.Activate(Object page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.Activate(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)        
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.ViewViewComponentResult.ExecuteAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentInvoker.InvokeAsync(ViewComponentContext context)
   at Microsoft.AspNetCore.Mvc.ViewComponents.DefaultViewComponentHelper.InvokeCoreAsync(ViewComponentDescriptor descriptor, Object arguments)
   at MyProject.Services.RenderViewComponentService.RenderViewComponentToStringAsync[TViewComponent](Object args) in MyProject\Services\RenderViewComponentService.cs:line ??
   at MyProject.Services.PdfService.DoWorkAsync(Foo foo) in MyProject\Services\PdfService.cs:line ??
   at MyProject.Services.PdfService.GenerateAsync() in MyProject\Services\PdfService.cs:line ??
   at MyProject.Controllers.MyController.Get() in MyProject\Controllers\MyController.cs:line ??
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker 
invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_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|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.HeaderPropagation.HeaderPropagationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)