当用户点击按钮时,我使用ThreadPool.QueueUserWorkItem
生成一个线程,该线程启动一个长时间运行的进程。我希望在线程完成后显示一个按钮,以便用户可以单击它。
ThreadPool
我想做什么?
其中一个页面在单击时有一个按钮连接到WS并启动一个创建文件的长时间运行的进程。在处理期间,我想向用户显示进度条。处理完成后,我想提供一个指向已创建文件的链接。许多用户将在创建不同文件的同时单击按钮。我想你会称之为可以使用异步方法实现的单个请求吗?
关于异步页面的快速问答:
MSDN链接具有以下代码:
AddOnPreRenderCompleteAsync( 新的BeginEventHandler(MyBeginMethod), 新的EndEventHandler(MyEndMethod) );
似乎MyBeginMethod
在页面加载时启动,如果我想在按钮点击时启动异步过程,那么相同的代码段是否适合我?
MyBeginMethod
和MyEndMethod
方法访问UI控件(以便我可以在流程完成时显示下载文件按钮吗?或者不同的线程是否拥有这些控件?答案 0 :(得分:4)
不。
你必须存储你在ASP.NET页面可用的地方完成的事实以及做你工作的方法,比如HttpCache。
如果这一切都在一个请求中发生,请跳过线程池并查看asynchronous pages.
首先,如果文件是按用户创建的,那么长时间运行操作的结果应存储在Session中,而不是缓存中。缓存在用户之间共享,会话是按用户进行的。
长时间运行的任务可以创建文件,然后将文件路径存储在该用户的会话中。每当用户发送另一个文件请求时,会检查该文件的会话。
在此过程中,UI有几个选项。一种是通过回发到服务器,另一种是ajax调用。
Ajax可能不是最容易的,尽管有很多框架(比如jQuery)和网上有关如何进行异步回发的大量信息。如果流程很长,用户可能会浏览等等,使您的任务更难实施。
另一种选择是发出对文件的请求,然后重定向到保留页面。此保留页面有一个脚本,每X秒自动刷新一次。它向用户显示诸如“请等待,创建文件”之类的通知。每次此页面回发到服务器时,都会检查文件是否存在。如果尚未准备就绪,那么您将返回到保留页面。最终,文件就绪,您可以将用户重定向到另一个下载/显示文件的页面。
第二个选项可能更容易,更直接地实现。这是伪代码:
答案 1 :(得分:1)
不,ThreadPool
中没有已完成的活动,Join()
也没有简单的方法。
这是Task类在.NET4中解决的问题之一。任务有一个Wait()方法。
同时,请遵循Will的回答中的建议。异步ASP.NET很容易出错。