asp.net进程中长时间运行的代码

时间:2008-09-22 23:45:00

标签: .net asp.net

E.g。我们这个代码在asp.net形式的codebihind:

private void btnSendEmails_OnClick()
{
    Send100000EmailsAndWaitForReplies();
}

此代码执行将被超时原因终止。 为了解决这个问题,我希望看到这样的事情:

private void btnSendEmails_OnClick()
{
    var taskId = AsyncTask.Run( () =>  Send100000EmailsAndWaitForReplies() );
    // Store taskId for future task execution status checking.
}

此方法将在特殊环境中以某种方式执行w3wp.exe进程。

有人知道用于解决此类问题的框架/工具集吗?

更新:电子邮件发送方法只是我的意思的一个例子。事实上,我可能需要在asp.net工作流程之外执行许多功能。

E.g。这一点对于一个应用程序非常重要,该应用程序聚合来自几个第三方服务的数据,对其执行某些操作并将其发送回另一个服务。

9 个答案:

答案 0 :(得分:5)

这已作为其他问题的一部分进行了讨论:

Multithreading in asp.net

BackgroundWorker thread in ASP.NET

没有好办法做到这一点。您不希望ASP.NET工作进程中有任何长时间运行的进程,因为它可能在您完成之前进行回收。

编写Windows服务以在后台运行,为您完成工作。将消息丢弃到MSMQ以启动任务。然后他们可以随心所欲地跑。

答案 1 :(得分:3)

  1. QueueBackgroundWorkItem我的示例显示了发送电子邮件。
  2. HangFire开源项目适用于共享托管。
  3. 在Azure上,您可以使用WebJobs
  4. 在Azure上,Cloud services

答案 2 :(得分:1)

我可以想到两个可能的路径:

  1. 您可以创建一个托管远程对象的Windows服务,并让您的Web应用程序调用该远程对象,以确保该方法在IIS进程空间之外执行。
  2. 您可以设置要记录请求的数据库或MSMQ。然后,您的Web应用程序可以监视请求的状态,以便随后通知用户它已完成。我会设想一个完成请求的服务。

答案 3 :(得分:1)

ASP.NET托管环境对于任何长时间运行的进程(CPU或I / O消耗)都非常危险,因为可能会发生突然的AppDomain卸载。

如果要在请求处理管道之外执行后台任务,请考虑使用http://hangfire.io,它可以为您处理后台处理的所有困难和风险,而无需安装其他Windows服务(但可以当它来的时候使用它们)。还有一个mail sending tutorial

答案 4 :(得分:0)

一种选择是让任务执行一定数量的电子邮件,然后将Response.Redirect重新发送回自身并重复,直到所有电子邮件都已发送。

答案 5 :(得分:0)

您可以拥有将邮件作为服务运行的功能。将请求提交给它,让它处理它。每隔一段时间查询一次状态。如果您可以控制服务器,则可以安装Windows服务,这可能是最佳处理和生命周期管理的理想选择。

答案 6 :(得分:0)

ASP.NET 2.0+支持异步页面的概念。将页面指令Async =“true”添加到您的页面。

然后在Page_Load中,使用BeginEventHandler和EndEventHandler委托使代码在相应的“处理程序”中异步执行。

<%@ Page Language="C#" Async="true" %>
<script runat="server">

  protected void Page_Load(object sender, EventArgs e)
  {
    BeginEventHandler begin = new BeginEventHandler(BeginMethod);
    EndEventHandler  end = new EndEventHandler(EndMethod);

    AddOnPreRenderCompleteAsync(begin, end);
  }
</script>

答案 7 :(得分:0)

当您的网站由共享托管服务提供商托管时,通常无法运行自定义Windows服务。运行一个你定时运行的单独线程可能会不一致,因为IIS会不时地回收你的线程,甚至在cofig文件中或通过代码设置脚本执行属性也不会确保你的线程不会被杀死并被回收。

我遇到了基于缓存过期的方法,该方法给出了共享主机服务上可用的方法可能是最安全的,即最一致的选项。本文非常好地解释了它并提供了一个作业队列类来帮助管理您在文章末尾的预定作业,请参阅此处 - http://www.codeproject.com/KB/aspnet/ASPNETService.aspx

答案 8 :(得分:-4)

Server.ScriptTimeout = 360000000;