简体   繁体   English

控制器中的 C# .NET Core 异步方法

[英]C# .NET Core async methods in controller

I'm relatively new to .NET Core and trying to get my head around async/await usage to help speed up a slow-loading page.我对 .NET Core 比较陌生,并试图了解异步/等待的使用,以帮助加快加载缓慢的页面。

My original controller method looked like this:我原来的控制器方法是这样的:

public IActionResult Index()
{
      //other code here

      regionVM.listEvents = getEvents(regionCatID);
      regionVM.listNews = getNews(regionCatID);
      regionVM.listLIA = getLIA(regionCatID);
      regionVM.listAwards = getAwards(regionCatID);

      return View("/Views/Regions/Index.cshtml", regionVM);
}

getEvents, getNews, getLIA, and getAwards are all other methods within the same controller. getEvents、getNews、getLIA 和 getAwards 是同一控制器中的所有其他方法。 The corresponding lists they populate in the view model are used to display four different areas in the view.它们在视图模型中填充的相应列表用于在视图中显示四个不同的区域。 This all populates properly, but is slow.这一切都正确填充,但速度很慢。

I read a lot of different articles and posts, but tried to update my code following this one in particular: How can I run both of these methods 'at the same time' in .NET 4.5?我阅读了很多不同的文章和帖子,但特别尝试在此之后更新我的代码: 如何在 .NET 4.5 中“同时”运行这两种方法?

My new method looked like this:我的新方法如下所示:

public async Task<IActionResult> Index()
{
      //other code here

      var eTask = Task.Run(() => getEvents(regionCatID));
      var nTask = Task.Run(() => getNews(regionCatID));
      var lTask = Task.Run(() => getLIA(regionCatID));
      var aTask = Task.Run(() => getAwards(regionCatID));

      regionVM.listEvents = await eTask;
      regionVM.listNews = await nTask;
      regionVM.listLIA = await lTask;
      regionVM.listAwards = await aTask;

      return View("/Views/Regions/Index.cshtml", regionVM);
}

This seemed to work and compiled without any errors, but now when the regions pages load it's sort of hit or miss whether the four areas actually populate in the view.这似乎可以正常工作并且编译没有任何错误,但是现在当区域页面加载时,这四个区域是否实际填充在视图中是有点命中或错过的。 For instance, sometimes the news area will be blank, when I know there are news items that should be populated and were populating with the old synchronous method.例如,有时新闻区域会是空白的,当我知道有应该填充的新闻项目并且正在使用旧的同步方法填充时。

Is the view loading before the tasks are done executing?是否在任务执行完成之前加载视图? Or am I going about this completely the wrong way?或者我会以完全错误的方式解决这个问题? Thanks for any suggestions.感谢您的任何建议。

There are different ways to handle this, but firstly, I would make sure to understand async/await.有不同的方法来处理这个问题,但首先,我会确保理解 async/await。 Microsoft has great articles and videos on the topic. Microsoft 有关于该主题的精彩文章和视频。

Also, I have no idea what the methods you are calling (eg getEvents) look like so my answer is assuming they are true async methods.另外,我不知道您调用的方法(例如 getEvents)是什么样的,所以我的回答是假设它们是真正的异步方法。

I would avoid Task.Run within ASP.NET Core apps generally speaking.一般来说,我会避免在 ASP.NET Core 应用程序中使用 Task.Run。 It only results in extra unnecessary Thread Pool scheduling.它只会导致额外的不必要的线程池调度。

 // Your new code can easily be rewritten as: public async Task<IActionResult> Index() { //other code here regionVM.listEvents = await getEvents(regionCatID); regionVM.listNews = await getNews(regionCatID); regionVM.listLIA = await getLIA(regionCatID); regionVM.listAwards = await getAwards(regionCatID); return View("/Views/Regions/Index.cshtml", regionVM); } // OR public async Task<IActionResult> Index() { //other code here var task1 = getEvents(regionCatID); var task2 = getNews(regionCatID); var task3 = getLIA(regionCatID); var task4 = getAwards(regionCatID); await Task.WhenAll(task1, task2, task3, task4); regionVM.listEvents = await task1; regionVM.listNews = await task2; regionVM.listLIA = await task3; regionVM.listAwards = await task4; return View("/Views/Regions/Index.cshtml", regionVM); }

Because the code in each of these examples is awaited, its guaranteed the when the regions page is rendered, the four areas will be populated because the line因为这些示例中的每个示例中的代码都是等待的,所以它保证在呈现区域页面时,将填充四个区域,因为该行

 return View("/Views/Regions/Index.cshtml", regionVM);

Is only executed once all the data has already been fetched.在已获取所有数据后执行。


There are others ways to also improve page performance if you want it to be rendered quickly.如果您希望快速呈现页面,还有其他方法可以提高页面性能。 For example , I'm not sure how much data is actually being fetched in your controller action, however, instead of only loading the page when all the data is returned, you can use ajax calls to fetch all this data.例如,我不确定在您的控制器操作中实际获取了多少数据,但是,您可以使用 ajax 调用来获取所有这些数据,而不是仅在返回所有数据时加载页面。 This way, your controller 'Index' action wont fetch all the data and your page will render immediately, then you make ajax calls from your javascript code to get data for each area.这样,您的控制器“索引”操作不会获取所有数据并且您的页面将立即呈现,然后您从您的 javascript 代码进行 ajax 调用以获取每个区域的数据。

A common example for doing this is something like a Dashboard page.执行此操作的一个常见示例是仪表板页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM