У меня есть совершенно новый проект ASP.Net MVC, который потребляет память и отказывается его выпускать по причинам, которые я не могу понять.
Приложение
На сайте всего 2 страницы, обе обслуживаются HomeController.
public class HomeController: Controller
{
public ActionResult Index()
{
GC.Collect();
return View();
}
public ActionResult List()
{
GC.Collect();
var homeViewModel = new HomeViewModel();
for (int i = 0; i < 300; i++)
{
homeViewModel.MyList.Add(new MyClass
{
Field1 = "AAAAAAAAAAAAAAAAAAAAAAAAAAA",
Field2 = "BBBBBBBBBBBBBBBBBBBBBBBBBBB",
Field3 = "CCCCCCCCCCCCCCCCCCCCCCCCCCC",
Field4 = "DDDDDDDDDDDDDDDDDDDDDDDDDDD",
Field5 = "EEEEEEEEEEEEEEEEEEEEEEEEEEE",
Field6 = "FFFFFFFFFFFFFFFFFFFFFFFFFFF"
});
}
return View(homeViewModel);
}
}
public class HomeViewModel
{
public List<MyClass> MyList { get; set; }
public HomeViewModel()
{
MyList = new List<MyClass>();
}
}
public class MyClass
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
public string Field5 { get; set; }
public string Field6 { get; set; }
}
Вы заметите, что и действия Index, и List вызывают сборку мусора в начале каждого вызова.
Страница индекса просто содержит общий файл _Layout.cshtml и никакого другого содержимого.
@model WebApplication1.Controllers.HomeViewModel
@{
ViewBag.Title = "Home Page";
}
Страница списка содержит таблицу из 300 строк, каждая из которых показывает 6 строковых свойств класса, предназначенных для демонстрации моей проблемы.
@model WebApplication1.Controllers.HomeViewModel
@{
ViewBag.Title = "List Page";
}
<table class="table table-condensed">
@foreach (var item in Model.MyList)
{
<tr>
<td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field1</td>
<td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field2</td>
<td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field3</td>
<td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field4</td>
<td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field5</td>
<td style="@MyHelpers.DetermineStrikethruStyle(true)">@item.Field6</td>
</tr>
}
</table>
Как видите, стиль ячеек в таблице основан на результатах Razor HTML Helper, как показано ниже:
@helper DetermineStrikethruStyle(bool isStrikeThru)
{
@(isStrikeThru ? "text-decoration: line-through;" : "")
}
Проблема
Ниже вы можете увидеть, как съедается память при каждом обновлении страницы списка.
При запуске — показывать домашнюю страницу
После обновления индексной страницы x 10
После отображения страницы со списком в первый раз
После отображения страницы списка во второй раз
После отображения страницы списка в третий раз
После четвертого отображения страницы со списком
После отображения страницы списка в пятый раз
Как избежать проблемы
Просто удалив вызовы Razor HTML Helper на странице списка, вы полностью избегаете этой проблемы.
@model WebApplication1.Controllers.HomeViewModel
@{
ViewBag.Title = "List Page";
}
<table class="table table-condensed">
@foreach (var item in Model.MyList)
{
<tr>
<td>@item.Field1</td>
<td>@item.Field2</td>
<td>@item.Field3</td>
<td>@item.Field4</td>
<td>@item.Field5</td>
<td>@item.Field6</td>
</tr>
}
</table>
При запуске — показывать домашнюю страницу
После обновления индексной страницы x 10
После отображения страницы со списком в первый раз
… после пятого раза
… после 25-го раза
… после 50-го раза
Есть идеи? Сейчас я в тупике, и в результате у меня непригодное для использования приложение.
Может ли кто-нибудь предложить какое-либо руководство?
HtmlHelper
, а не использовать синтаксис@helper
? - person Chris Pratt   schedule 26.04.2017