很抱歉,如果这是一个很长的问题,我需要一些关于人们认为最好的方法的建议(因为有一些)。
目前,我的项目有一个方法
do_job(jobid,userid)
此方法需要一两分钟,然后重定向到另一个页面。
这已经被重写,现在它在后台运行并重定向到另一个页面,同时do_job的线程继续。 - 这很好。
在default.aspx页面的button_click事件中:
Dim d as New do_job_delegate(AddressOf do_job)
d.BeginInvoke(jobid,userid, New AsyncCallback(AddressOf Callback),d)
Response.redirect("results.aspx")
与
有关Delegate Sub do_job_delegate(Byval jobid as integer, Byval userid as integer)
Public Sub do_job(Byval jobid as integer, Byval userid as integer)
' Do something for several seconds
End Sub
Public Sub Callback(Byval ar As IAsyncResult)
ar.AsyncState.EndInvoke(ar)
End Sub
这基本上可以满足我的需求,用户可以在网站上进行操作,do_job方法在后台运行并成功完成任务。
但是,我现在已添加到这个do_job方法中,并且有几个小任务,每个任务在do_job中占用30秒左右,并且它们可以/应该使其并行运行。 e.g
Public Sub do_job(Byval jobid as integer, Byval userid as integer)
loop through between 1 or more (up to roughly 10 items)
'process that takes about 30 seconds
end loop
End Sub
所以我想要发生的是 - do_job占用的最长时间是最长作业的最长时间(30秒),而不是 - 30秒x作业数量=此刻所需的时间。
由于我已经使用委托来从ui中删除流程,任何人都可以就如何重新安排我的do_job方法提供任何建议/最佳实践,以便它可以处理并发任务以进一步提高整体速度。 / p>
谢谢!
答案 0 :(得分:4)
我建议您在花费大量时间之前考虑将工作转移到单独的服务而不是在Web服务器上内联运行。
只需将记录放入db表并让服务观察它。
以下是Phil Haack的一篇文章,解释了为什么你不应该在网络服务器上搞乱线程。
就并行执行任务而言,请查看.net 4.0并行库。他们使这种事情变得非常容易。
答案 1 :(得分:1)
正如@BNL所说,这应该在Web请求/响应管道之外的服务或其他进程中完成。当前方法的一个潜在严重问题是,如果您获得大量流量,那么您将产生比系统可以合理处理的线程更多的线程。这消除了您在单个用户环境中从多线程中获得的任何好处,事实上,它可能会增加很多开销,导致响应速度比单线程方法慢。
考虑在数据库表中放置必须完成的任务的描述:
id
job_id
user_id
date_created
date_started
date_completed
status_code
并让您的服务轮询该表以查找需要处理的作业。这为您提供了许多额外的好处,包括生成成功/失败报告的能力,将在IIS重置期间保持的作业排队等。如果Web应用程序需要在作业完成时提醒用户,请检查页面加载(简单)或定期通过AJAX请求(不太容易),就像StackOverflow在检查您正在阅读的问题的新响应时所做的那样。
See this article for an overview of creating services in VB.NET.
如果做不到这一点,通过Parallel.For
和Parallel.ForEach
并行启动大量类似任务的简单方法,但我不能强调这在网络或其他多方面有多危险用户环境。
此外,您应该区分 ASP.NET版本和 .NET框架版本。许多/大多数服务器应该可以使用.NET框架4,即使他们的站点使用的是ASP.NET 2。
See this MSDN article for an example of the latter,但服务真的是要走的路。