임 로딩 최대의 웹 페이지 (면도기) 및 (내 세계) 때문에, 지금이실행 여러 병렬
var webPage = WebPage.CreateInstanceFromVirtualPath(_relativeFilePath);
var httpContext = new HttpContextWrapper(HttpContext.Current);
var startPage = StartPage.GetStartPage(webPage, "_PageStart", new[] { "cshtml" });
var pageContext = new WebPageContext(httpContext, webPage, startPage);
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
webPage.ExecutePageHierarchy(pageContext, writer);
}
string output = sb.ToString().Trim();
처럼 내 .cshtml 파일을 실행, 각 .cshtml 파일은 자체에 포함 된 단위는 내가한다 위에서 N 번 병렬로 실행되는 코드를 가질 수 있지만 드물 긴하지만 예외적 인 경우도 있습니다.
System.InvalidOperationException: Stack empty.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.Stack`1.Pop()
at System.Web.WebPages.TemplateStack.Pop(HttpContextBase httpContext)
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.WebPages.WebPage.ExecutePageHierarchy(IEnumerable`1 executors)
at System.Web.WebPages.WebPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
병렬 처리를 비활성화하고 모든 .cshtml 파일을 하나씩 실행하면 예외가 트리거되지 않습니다. 따라서 WebPages의 내부 동작이 스레드로부터 안전하지 않은지 궁금해하며 ExecutePageHierarchy
에 대한 각각의 호출이 현재 비 고유 값에 액세스하는 것일 수도 있습니다. HttpContext
일부는 TemplateStack가 HttpContext.Items에 정적 키를 사용하여 저장됩니다임을 밝혀 파고 이 예외가 Throw되는 이유 해결 방법은 Items 속성을 HttpContextWrapper의 하위 클래스로 분리하여 각 병렬 반복이 고유 한 스택을 갖도록하는 것입니다. 그게 효과가 있니? –
@ Pouli가 작동 할 수도 있지만 매우 지원되지 않습니다. 당신이하는 일은 ASP.NET 내부 구조를 파헤 치고 작동 방식을 약간 바꿔서 결과를 예측할 수 없으며 시스템에 대한 가장 간단한 패치/변경/업그레이드로 깨질 수 있습니다. 따라서이 접근법을 권장하지 않습니다. CSHTML 페이지는 동일한 요청 내에서 병렬로 실행되지 않습니다. – Eilon