如何异步运行长时间运行的操作并在 ASP.Net Ajax 中为用户显示加载并轮询结果?
Posted
技术标签:
【中文标题】如何异步运行长时间运行的操作并在 ASP.Net Ajax 中为用户显示加载并轮询结果?【英文标题】:How to run long running operation asynchronously and show loading for the user in ASP.Net Ajax and poll for the result? 【发布时间】:2011-03-24 11:43:28 【问题描述】:我的 asp.net 应用程序需要很长时间才能完成繁重的操作。我不想在一个请求中运行整个操作,这可能会导致 TimeOut 错误。相反,我想在一个单独的线程中调用该操作并每隔 x 秒轮询一次结果。我该怎么做?
如果操作完成,我需要在 ajax 回发中注册一个脚本来隐藏加载面板并显示内容。但是我无法注册新脚本并在 ajax 回发期间调用它。
有什么想法吗?
【问题讨论】:
你不能注入任何javascript吗? 由于脚本是在页面中注册的,因此我猜在发送页面的部分更新时不会将新脚本发送给客户端。 使用 ScriptManager 注册您的脚本。请参阅此处的定义msdn.microsoft.com/en-us/library/bb310408.aspx 【参考方案1】:选项 1
在您的代码隐藏中,您可以启动一个线程并拥有一些管理正在运行的线程的类。然后,您可以在 UpdatePanel 中拥有一个控件,该控件每隔几秒轮询一次进度。
选项 2
将“待办事项”的详细信息存储在数据库中,并让后台服务不断检查待办事项。它将完成工作并报告进展。您将拥有类似于选项 1 的控件,用于检查进度并更新 UI。
【讨论】:
我的页面中有多个 Web 部件,每个我想创建一个线程(我希望它们独立加载)。在这种情况下,即使有 1000 个用户同时连接并且我在一个页面中有 10 个 Web 部件,它不会创建 10000 个线程吗?有这么多线程是完全正常的吗? 两件事。如果您知道所有需要提前完成的工作,那么使用 Parallel.ForEach() 来并行处理这些项目。这是利用具有多个处理器或内核的系统的最有效方式。如果您想使用线程,使用 ThreadPool.QueueWorkitem() 将您的项目排队等待工作(而不是 new Thread())很重要。 ThreadPool 将管理和重用线程,这在性能方面比创建自己的新线程要好得多。如果您将 1,000 个项目排队,线程池将在线程可用时处理它们。希望对你有帮助! 考虑到任何使用线程的选项,它可以访问什么Session
对象?
@NikhilGirraj 您应该将会话中所需的任何信息传递给在另一个线程上执行的函数。【参考方案2】:
在回发时,我将创建一个线程来启动长时间运行的进程并注册客户端启动脚本。客户端脚本将使用 setTimeOut 调用您的预定义 js 函数来启动第一个 Web 服务调用以进行状态更新池。如果结果显示已完成,您可以在 javascript 中更改面板可见性。否则,它将安排在 x 毫秒后再次通过 setTimeOut 调用再次调用您的 js 函数。
【讨论】:
正如我在进行部分回发时所说,我无法注册新脚本并调用它。 ClientScriptManager 注册脚本仅在初始渲染时运行,但您应该能够使用 ScriptManager.RegisterStartupScript 通过回发进行部分渲染。以上是关于如何异步运行长时间运行的操作并在 ASP.Net Ajax 中为用户显示加载并轮询结果?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用javascript在asp.net上停止正在进行的回发(长时间运行)?
ASP.NET Web 表单 - 如何异步调用 WCF 异步方法?
ASP.NET Core 6框架揭秘实例演示[21]:如何承载你的后台服务