【问题标题】:Can requests be handled on a separate thread?请求可以在单独的线程上处理吗?
【发布时间】: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


【解决方案1】:

异步方法不就是用于这种事情的吗?

不,async 不会更改 HTTP 协议。每个请求仍然只有一个响应,并且该响应只能发送一次。

async 释放调用线程,但在 ASP.NET 上,这仅意味着线程返回到线程池并能够处理其他请求;它不会向用户发送 HTTP 响应。在您的特定情况下,代码首先从线程池 (StartNew) 中获取一个线程,以便从线程池 (await) 中释放一个线程,这是没有意义的。

有一些解决方案应该可行。您可以删除会话状态或将此调用替换为 SignalR 集线器(在旧的集线器完成时允许其他用户请求),或者您可以执行此 AJAX 样式 - 最好使用 reliable queue connected to an independent worker process

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 2013-08-12
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-30
    • 2013-04-13
    • 2020-04-22
    相关资源
    最近更新 更多