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

时间:2020-03-06 14:34:19  来源:igfitidea点击:

例如。我们将此代码以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工作流程之外执行。

例如。这一点对于一个应用程序非常重要,该应用程序聚合来自几个第三方服务的数据,然后对其进行处理并将其发送回另一个服务。

解决方案

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

我可以想到两种可能的走法:

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

Server.ScriptTimeout = 360000000;

我们可能具有将邮件作为服务运行的功能。将请求提交给它,然后让它处理。偶尔查询其状态。如果我们可以控制服务器,则可以安装Windows服务,这可能是实现最佳处理和生命周期管理的理想选择。

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>

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

ASP.NET中的多线程

ASP.NET中的BackgroundWorker线程

没有好的方法可以做到这一点。我们不希望ASP.NET辅助进程中有任何长时间运行的进程,因为它可能会在完成之前回收。

编写Windows服务以在后台为我们运行。将消息放入MSMQ以启动任务。然后它们可以运行任意长时间。