【问题标题】:BackgroundWorker thread in ASP.NETASP.NET 中的 BackgroundWorker 线程
【发布时间】:2014-06-11 01:33:28
【问题描述】:

是否可以在ASP.NET 2.0 中使用BackGroundWorker线程用于以下场景,让浏览器端的用户不用等待很长时间?

场景

  1. 浏览器请求一个页面,比如 SendEmails.aspx
  2. SendEmails.aspx 页面创建一个 BackgroundWorker 线程,并为该线程提供足够的上下文来创建和发送电子邮件。
  3. 浏览器收到来自 ComposeAndSendEmails.aspx 的响应,表示正在发送电子邮件。
  4. 同时,后台线程正在进行创建和发送电子邮件的过程,这可能需要相当长的时间才能完成。

我主要关心的是保持 BackgroundWorker 线程运行,尝试发送 50 封电子邮件,而 ASP.NET 工作进程线程池线程早已不复存在。

【问题讨论】:

标签: asp.net multithreading


【解决方案1】:

如果您不想使用 AJAX 库,或者电子邮件处理时间非常长并且会使标准 AJAX 请求超时,您可以使用 AsynchronousPostBack 方法,它是 .net 1.1 中的“旧技巧”天。

基本上,您所做的就是让您的提交按钮以异步状态开始电子邮件处理,同时将用户带到一个中间页面。这样做的好处是您可以根据需要尽可能多地刷新中间页面,而不必担心达到标准超时。

当您的后台进程完成后,它会在数据库/应用程序变量/其他任何内容中放置一个“完成”标志。当您的中间页面进行自身刷新时,它会检测到此标志并自动将用户重定向到“完成”页面。

同样,AJAX 使所有这些都没有实际意义,但如果由于某种原因您有一个非常密集或及时的过程必须通过网络完成,那么这个解决方案将适合您。我找到了一个很好的教程 here 并且还有很多。

当我们正在开发一个与第三方应用程序交互的“网络签到”类型的应用程序并且它们的导入 API 非常慢时,我不得不使用这样的过程。

编辑:嘎!诅咒你 Guzlar 和你神一样的打字能力 8^D。

【讨论】:

    【解决方案2】:

    您不应该从 ASP.NET 页面执行任何线程。当工作进程回收时,任何长时间运行的线程都有被杀死的危险。你无法预测何时会发生这种情况。任何长时间运行的进程都需要由 Windows 服务处理。例如,您可以通过在 MSMQ 中删除消息来启动这些过程。

    【讨论】:

    • 这在托管环境中通常是不可能的。然后缓存删除技巧最适合我。
    【解决方案3】:
    ThreadPool.QueueUserWorkItem(delegateThatSendsEmails)
    

    或在 System.Net.Mail.SmtpServer 上使用 SendAsync 方法。

    您希望将电子邮件发送代码放在另一个线程上,因为这样它会立即返回用户,并且只会处理,无论需要多长时间。

    【讨论】:

      【解决方案4】:

      这是可能的。从页面异步启动新线程后,页面请求将继续并将页面发送回用户。异步线程将继续在服务器上运行,但不再有权访问会话。

      如果您必须显示任务进度,请考虑一些 Ajax 技术。

      【讨论】:

        【解决方案5】:

        您需要在此场景中使用异步页面,这是 ASP.NET 2.0 中添加的一项功能

        异步页面提供了一个整洁的 引起的问题的解决方案 I/O 绑定请求。页面处理 从线程池线程开始,但是 该线程返回给线程 池一次异步 I/O 操作开始于响应 来自 ASP.NET 的信号。当。。。的时候 操作完成,ASP.NET 抓取 线程池中的另一个线程 并完成对请求的处理。 可扩展性增加是因为 线程池线程使用较多 有效率的。线程会 否则卡在等待 I/O 到 完成现在可以用于服务 其他请求。直接 受益人是不 执行冗长的 I/O 操作,并且可以 因此进出 快速流水线。漫长的等待 进入管道有一个 不成比例的负面影响 此类请求的执行情况。

        http://msdn.microsoft.com/en-us/magazine/cc163725.aspx

        【讨论】:

          【解决方案6】:

          如果你想在你的 ASP 页面中使用多标题,你可以使用这样的简单线程模型:

          {
              System.Threading.Thread _thread = new Thread(new ThreadStart(Activity_DoWork));
              _thred.Start();
          }
          Activity_DoWork()
          {
              /*Do some things...
          }
          

          此方法适用于 ASP 页面。带有 BackgroundWorker 的 ASP 页面不会启动,而 BackgroundWorker 将完成。

          【讨论】:

          • 如果我在 Activity_DoWork 中进行无限操作。工作进程回收后线程还在运行吗?
          【解决方案7】:

          5 年后,但问题依旧……如果您想从应用程序中执行即发即弃的操作,并且忘记与 ASP.NET 应用程序中的后台作业处理相关的所有困难,您可以使用http://hangfire.io

          • 它不会在回收过程中丢失您的作业,因为它使用持久存储来保存有关后台作业的信息。
          • 它会自动重试因暂时异常(SMTP 服务器连接错误)而中止或失败的后台作业。
          • 它允许您通过集成的 Web 界面轻松调试后台作业。
          • HangFire 非常容易安装/配置/使用。

          还有 Sending Mail in Background with ASP.NET MVC 使用 HangFire 和 Postal 的教程。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-03
            相关资源
            最近更新 更多