【问题标题】:Background processing in .Net - advice required.Net 中的后台处理 - 需要建议
【发布时间】:2012-02-08 15:08:06
【问题描述】:

对不起,如果这是一个很长的问题,我需要一些关于人们认为最好的方法的建议(因为有一些)。

目前,我的项目有一个方法

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 秒左右,并且可以/应该使它们并行运行。 例如

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 方法提供任何建议/最佳实践,以便它可以处理并发任务以进一步提高整体速度。

谢谢!

【问题讨论】:

    标签: asp.net vb.net delegates asp.net-2.0 background-process


    【解决方案1】:

    我建议您在花费大量时间之前考虑将工作转移到单独的服务,而不是在您的网络服务器上内联运行它。

    只需将一条记录放入数据库表中并让服务监视它。

    这是 Phil Haack 的一篇文章,解释了为什么你不应该在你的网络服务器上搞乱线程。

    http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx

    就并行执行任务而言,请查看 .net 4.0 并行库。他们让这种事情变得超级简单。

    http://msdn.microsoft.com/en-us/library/dd460717.aspx

    【讨论】:

    • 感谢您的快速回复,不幸的是我被困在 asp 2.0 上来完成当前的工作。
    • @AndyGreen 然后提供服务。 .NET 的一个好处是您可以使用您已经熟悉的语言等来构建它。
    • 如果您的组织允许,您始终可以将 .net 4 用于服务,同时将 Web 保留为 2.0。如果您的组织不允许,请找一份新工作。 :)
    • 感谢您的指点,将服务用作单独的实体听起来像是前进的方向! (虽然新工作是一个更好的主意!:-D)
    • @AndyGreen 查看我对 .NET 版本的编辑; ASP.NET 版本和 .NET 框架版本不一定对应(尽管向招聘人员解释这一点祝你好运!)。任何有最新补丁等的服务器都应该安装 .NET 4 框架。
    【解决方案2】:

    正如@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.ForParallel.ForEach,但我无法强调这在网络或其他多用户环境中有多危险。

    此外,您应该区分 ASP.NET 版本.NET 框架版本。许多/大多数服务器应该有可用的 .NET framework 4,即使他们的站点使用 ASP.NET 2。

    See this MSDN article for an example of the latter,但是服务确实是要走的路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-04
      • 2022-11-11
      • 1970-01-01
      • 2016-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多