2014-02-21 5 views
0

여기에서 대답 (https://stackoverflow.com/a/2759898)을 사용하여 뷰를 문자열로 렌더링합니다.뷰를 문자열로 렌더링 (비동기)

비동기를 처음 사용합니다. 보기가 렌더링 될 때까지 다음 코드가 실제로 자원을 릴리스하는지 여부를 알아야합니다. 내보기를 렌더링하는 데 5 초가 걸릴 것이라고 가정합니다.

public async Task<string> RenderViewToString(string viewName, object model) 
{ 
    ViewData.Model = model; 
    using (var sw = new StringWriter()) 
    { 
    return await Task.Run(() => 
    { 
     var razor = new RazorViewEngine(); 
     var viewResult = razor.FindView(ControllerContext, viewName, null, false); 
     var viewContext = new ViewContext(ControllerContext, viewResult.View, 
     ViewData, TempData, sw); 
     viewResult.View.Render(viewContext, sw); 
     viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); 
     return sw.GetStringBuilder().ToString(); 
    }); 
    } 
} 

P. 왜 내 견해가 렌더링하는 데 시간이 걸릴지 내게 묻지 마라. 권장되는 방법은 아니지만 특정 인스턴스에 대해서는 뷰에서 소수의 웹 서비스를 호출하고 json 출력을 만들어야합니다.

답변

1

뷰가 웹 서비스를 호출하는 경우 MVC 패턴을 따르지 않습니다. 뷰를 "렌더링"하는 데 필요한 시간에는 웹 서비스 호출을 수행하는 데 필요한 시간이 포함되어서는 안됩니다. 컨트롤러를 사용하고 모든 웹 서비스 결과/데이터가 포함 된 완성 된 모델을 뷰에 전달하면 뷰 또는 기타 리소스를 보유하는 데 아무런 걱정이 없습니다 ...

또한 결과가 표시 될 때까지 뷰를 가질 수있는 논리적 인 이유가 없습니다. Json - JsonResult를 반환하는 컨트롤러 만 있으면됩니다.

+0

나는 그 나쁜 습관을 알고 있지만 절박한 문제로 우리 프로젝트의 일시적인 해킹으로이 방법을 절실히 필요로합니다. 우리는 곧 그것을 고칠 예정입니다. – user3219798

2

아니요. 이것은 실제로 ASP.NET 스레드 풀에서 Task.Run()의 본문을 실행하는 다른 스레드를 얻는 것입니다. Task.Run()이 실행되는 동안 요청 스레드는 스레드 풀로 반환됩니다. Task.Run()가 끝나면 해당 스레드를 반환하고 요청을 끝내기 위해 하나를 얻습니다. 이 모든 코드는 작업을 추가하는 것입니다 ... 실제로 문제가 악화되고 있습니다.

보기에서 웹 서비스를 호출하는 경우 웹 서비스를 비동기 적으로 호출 할 수 있는지 확인하십시오. 비동기/대기가 효율성을 높일 수있는 곳입니다.

+0

실제로 Task.Run이 실행될 때 스레드가 풀로 반환됩니다 (그게 내가 원하는 것입니다). 나는 확신 할 수 없다. 보통의 경우, 스레드가 5 초 동안 VIEW에 전용 될 것이다 (보기가 5 초 동안 완료된다면)? – user3219798

+0

예, 요청 스레드가 풀로 반환되지만 'Task.Run()'에서 작업을 수행하기 위해 동일한 풀의 다른 스레드를 당겨서 완료 될 때까지 중단하고 풀에 반환하고 마지막으로 요청을 완료하기위한 스레드를 얻습니다. 전체 요청에 대한 요청 스레드에 매달려있는 것과 비교하면 아무 것도 얻지 못합니다. 실제로 스레드를 교환하는 오버 헤드로 인해 더 나쁩니다. 앱의 확장 성이 떨어지고 성능이 떨어집니다. –

+0

ViewResult가 완료되면 모든 스레드를 해제하고 알림을받는 방법을 제안 해 주실 수 있습니까? – user3219798

0

이 부분을 분명히 사용하지는 않지만 Ajax를 사용하여 반환 할 수 있도록 렌더링 된 뷰를 얻으려는 것으로 추측하고 페이지의 특정 영역 .

음, 이것은 올바른 MVC 방식이 아닙니다. Rob이 말했듯이, 당신은 JsonResult를 사용하려고 시도해야합니다. 웹 서비스에서 반환 된 데이터가 뷰로 전달되도록하려면 JsonResult를 얻고 Ajax를 사용하여이 메서드를 호출하는 것이 좋습니다.

또한이 렌더링 된 뷰를 문자열로 사용하여 페이지 또는 요소의 내용을 대체하려는 경우 더 나은 방법은 일부 부분 뷰를 만들고 뷰를 @ Html.Action으로 호출하는 것입니다 "보기", "컨트롤러"). 이렇게하면 html을 얻을 수 있습니다. Ajax를 사용하여 호출하고 뷰를 표시 할 컨테이너 요소로 밀어 넣을 수도 있습니다.

관련 문제