asp.net-mvc – 如何使ASP.Net MVC控制器动作异步
我的愿望是创建一个MVC控制器Action,它可以异步执行长时间运行的i / o操作.我的目标是避免在这个长时间运行的方法完成时绑定ASP.Net线程池中的线程.
该行动打了两个电话. 第一个调用是第三方dll,它不包含任何异步方法.这个DLL从专有数据库读取并执行相当复杂的cpu绑定处理.返回可能需要几秒钟的时间. 第二个调用使用第一个调用的结果作为使用Entity Framework传递给数据库查询的参数. 简化,这是动作: public async Task<ActionResult> MyActionAsync(arg1,arg2) { var parameters = 3rdPartyComponent.TakesLongTime(arg1,arg2); Task<List<MyClass>> genericList = null; using (DbContexts.MyDbContext db = new DbContexts.MyDbContext()) { genericList = await db.Database.SqlQuery<MyClass>(sql,parameters).ToListAsync(); } return View("MyView",genericList); } 我想打电话给3rdPartyComponent等待.我最初的想法是这样做: var parameters = await Task.Run(() => 3rdPartyComponent.TakesLongTime()).ConfigurateAwait(false); 但我已经阅读了几位主题专家明确表示在asp.net MVC Action中使用Task.Run()会适得其反,永远不应该这样做. 3rdPartyComponent是一个黑盒子的编译代码,它不能改变添加异步方法. 是否有任何方法可以调用3rdPartyComponent,以便整个Action运行而不会占用asp.net线程池中的线程? 解决方法
代码已经尽可能好了. Task.Run和Task.Factory.StartNew都不会给你带来任何好处(即使你传递了LongRunning标志). 由于第三方dll执行CPU绑定代码,因此需要一个线程.即使您可以修改它,也只能使db访问(I / O工作)异步;根据定义,CPU工作是同步的,从你的描述来看,听起来像CPU工作的工作在大多数时候都是如此. 关于在ASP.NET上避免Task.Run(以及甚至更糟的Task.Factory.StartNew)的全部观点是它们导致效率较低的行为.通过释放ASP.NET请求线程,您只需将线程返回到线程池,而不使用它;关于ASP.NET请求线程没什么神奇或特殊的.因此,Task.Run通过切换到另一个线程池线程来释放一个线程池线程,而使用LongRunning的Task.Factory.StartNew通过创建一个全新的线程释放一个线程池线程,将工作安排到该线程,然后拆除该线程最后的线程(此行为未记录,也未指定,但它是当前观察到的行为). 所以你最终做的只是招致不必要的线程切换(在StartNew的情况下,是一个完整的额外线程). ASP.NET旨在处理同步和异步工作;如果你有同步代码,最好的办法就是直接执行它,就像你的代码已经在做的那样. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- MVVM(Knockout.js)的新尝试:多个Page,一个ViewModel
- 微信--企业会话--示例
- asp.net – 在IIS7.5中什么模块删除了400个错误请求的正文
- asp.net-mvc – 是否有一个ASP.NET MVC HtmlHelper的图像链
- CLR调试器,ASP.NET – 如何增加超时?
- 带有声明性数据的Eval绑定ASP.NET
- asp.net-mvc – 如何填充mvc剃刀部分视图
- asp.net – UserHostAddress提供错误的IP
- asp.net-mvc – 适用于典型n层架构的Web API在哪里?
- ASP.NET自定义控件:何时调用LoadPostData()?