2014-02-21 3 views
0

Я использую здесь ответ (https://stackoverflow.com/a/2759898), чтобы отобразить как строку.Render Посмотреть как строку (Async)

Я новичок в асинхронном ожидании. Просто нужно знать, будет ли следующий код фактически освобождать ресурсы до отображения представления? Просто предположим, что мой взгляд займет 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.S. Не спрашивайте меня, почему мои взгляды потребуют времени для рендеринга. Хотя это не рекомендуется, но для этого конкретного экземпляра мне нужно вызвать несколько веб-сервисов в представлении и создать json-выход.

ответ

1

Вы не следуете шаблону MVC, если ваши представления вызывают веб-службы - время, необходимое для «рендеринга» ваших представлений, не должно включать время, необходимое для совершения вызовов веб-сервиса, - вы должны сделать все это в контроллер и передать завершенную модель со всеми результатами/данными веб-служб в представление - тогда нет никакой озабоченности в отношении размещения на представлениях или других ресурсах ...

Кроме того, нет логической причины даже иметь представление, когда результат Json - у вас должен быть только контроллер, который возвращает JsonResult.

+0

Я знаю его плохую практику, но мне отчаянно нужно это делать как временный взлом в нашем текущем проекте в срочном порядке. Мы скоро это исправим. – user3219798

2

Нет. Что это значит, это на самом деле получение другого потока из пула потоков ASP.NET для запуска тела Task.Run(). Во время выполнения Task.Run() поток запроса возвращается в пул потоков. И как только Task.Run() заканчивает, он возвращает этот поток и получает его для завершения запроса. Весь этот код делает, это добавление работы ... это на самом деле еще хуже.

Если представления вызывают веб-службы, обратитесь к асинхронному вызову веб-сервисов. Именно здесь async/await повысит эффективность.

+0

Фактически, когда Task.Run выполняет поток, возвращается в пул (это то, что я хочу). Я не уверен, если в нормальном случае поток будет посвящен VIEW в течение 5 секунд (если просмотр занимает 5 секунд)? – user3219798

+0

Да, поток запроса возвращается в пул, но он вытягивает другой поток из одного пула, чтобы выполнить работу в 'Task.Run()', и он будет висеть на нем до завершения, затем возвращает его в пул и наконец, получить поток для завершения запроса. Вы не набираете ничего по сравнению с тем, что просто зависаете с потоком запроса для всего запроса. На самом деле это хуже из-за накладных расходов на обмен файлами. Это делает приложение менее масштабируемым и менее эффективным. –

+0

Можете ли вы предложить, как освободить все потоки и получить уведомление, когда ViewResult будет завершен? – user3219798

0

Хотя контекст того, где вы собираетесь использовать это неясно, я бы просто предположил, что вы пытаетесь получить визуализированное представление, чтобы его можно было вернуть с помощью Ajax и просто разрешили бы вам обновлять определенную область страницы ,

Ну, это не правильный способ MVC. Как сказал Роб, вы должны попробовать использовать JsonResult. Если вы считаете, что хотите, чтобы возвращаемые данные из веб-службы были переданы в представление, лучше попытайтесь получить JsonResult и вызовите этот метод с помощью Ajax.

Кроме того, если вы пытаетесь каким-то образом заменить содержимое своей страницы или элемента, используя этот визуализированный вид как строку, лучшим подходом было бы просто создать некоторые частичные представления и вызвать их в представлении как @ Html.Action ("Просмотр", "контроллер"). Таким образом вы даже получите html. Вы также можете вызвать его с помощью Ajax и нажать его в элемент контейнера, где вы хотите отобразить представление.

Смежные вопросы