【发布时间】:2015-08-09 03:45:42
【问题描述】:
在我的 ASP.NET MVC Web 应用程序中,我正在使用有时可能需要很长时间才能响应的 Web 服务。在这种情况下,用户可能希望取消请求并能够发出其他请求。但由于服务器仍在忙于处理前一个请求,用户必须等待该请求完成。出于这个原因,我决定创建一些异步执行密集 IO 作业的操作方法,希望主线程不会被阻塞。但这无济于事。这是我的方法:
1:public class TestController:AsyncController{
2: public async Task<ActionResult> GetString(){
3:
4: string data=await Task<string>.Factory.StartNew(()=>{
5: return service.GetDataAsString("name");
6: });
7: return View(data);
8: }
9:}
除非服务返回预期的字符串,否则不会执行第 7 行,因此仍然存在阻塞。我必须做什么才能使整个操作在单独的线程中发生?我必须走旧时尚吗?异步方法不就是针对这种事情的吗?
【问题讨论】:
-
很可能,你看错了方向。可能导致您的问题的是会话锁定。尝试禁用它,用下一个属性装饰控制器:[SessionState(SessionStateBehavior.Disabled)]
-
这显然会禁用我不想要的会话状态。如果这是唯一的方法,那么这意味着我必须牺牲两者中的任何一个:会话或用户体验。我说的对吗?
-
@MikeJM - 我认为你所追求的是 Fire & Forget。或者,您可以将您的操作分为 2 个操作(一个用于返回视图,另一个用于执行服务调用)并执行来自客户端的 2 个单独的请求。
-
@MikeJM 如果我的猜测是正确的,那就是真正导致问题的原因。那么是的,你必须找到黄金中间。根据您的方案,您可以将 SessionStateBehavior 设置为 ReadOnly。或者将有问题的方法移动到单独的控制器,您将能够禁用会话或其他东西
-
异步操作在您的情况下没有用。您仍然在操作中启动一个新的工作线程来获取数据,因此它几乎比简单地使用同步操作更糟糕。我建议
GetString操作只需返回一条消息“正在加载数据...”,同时您启动排队任务以获取数据。然后在 UI 中,使用 ajax 定期检查获取状态(你也可以使用一些漂亮的进程栏:P)。
标签: asp.net-mvc multithreading async-await httprequest