ASP.NET MVC 4中的异步操作

5

我有一个同步调用,我需要将其转换为异步,我正在使用async/await关键字,但这只会在任务完成后返回一次结果,我需要逐个将结果返回到UI。

场景是,在用户验证后,我会向用户显示任务列表,但是我希望在从数据库检索到任务后逐个加载任务。以下是我的actionResult,它将搜索条件组合在一起以预过滤任务:

public async Task<ActionResult> Index(string searchTerm = null, int page = 1)
{
    Shared.InitialiseCriteria(SearchCriteria);
    SearchCriteria.DepartmentID = DepartmentID;
    SearchCriteria.PageSize = 15;
    SearchCriteria.FreeText = searchTerm;

    var model = await DoStuff(SearchCriteria);

        if (Request.IsAjaxRequest())
        {
            return PartialView("_ConversationList", model);
        }
    return View(model);

 }

这里是一个await任务,它调用GetConversation函数,该函数本质上获取了任务,当找到第一个任务时,我需要将其加载到Index视图中:

private async Task<Result> DoStuff(CSearchCriteria SearchCriteria)
{

   return GetConversations(SearchCriteria);
}

你能进一步解释一下你期望发生的事情以及实际发生了什么吗? - sinelaw
我希望从数据库中找到的任务可以一个接一个地加载到部分视图中,这样用户就不必一直盯着加载屏幕看了。目前,仅加载四个任务就需要大约10秒钟的时间。如果需要,我可以提供更多信息... - user2711252
2个回答

4
ASP.NET MVC中异步控制器的唯一目的是在异步操作进行时释放IIS线程以管理其他请求。从调用者的角度来看,与使用同步控制器相同。因此,我认为您无法通过异步控制器实现您想要的内容(您可以使用它,但它无法解决您的问题)。我认为您可以在服务器端实现某种分页来检索数据部分,并通过SignalR将其发送到客户端。

+1. 我有一篇博客文章解释了async不会改变HTTP协议 - Stephen Cleary
@Alex,谢谢您的回复。您能否给我一些建议,告诉我如何实现期望的结果?我也尝试了线程,但不确定如何在从数据库检索到第一个任务后刷新/更新我的索引视图。 - user2711252
我已经更新了一个答案,并附上了我的意见,如何做到这一点。 - Oleksandr Kobylianskyi

0

这里有几个问题:

  • 如何使ASP.NET在每个项目可用时立即开始返回数据,
  • 如何协调客户端和服务器,以便客户端知道新项目已经可用(即使它可以单独解析响应中的每个项目,或者如果您正在寻找“拉”则可以请求更多数据)

正如AlexK的答案所解释的那样,async api不会改变服务器响应客户端的方式。异步仅允许您的应用程序在未使用线程时释放它们,并使依赖于多个资源的请求部分并行化更容易。

除了使用专为此设计的SignalR之外,您还可以自己使用内置的低级机制-PushStreamContent。以下是关于如何执行此操作的几篇博客文章:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接