即使客户端浏览器页面已关闭,也要确保Web服务器的查询完成

时间:2014-08-04 11:14:29

标签: sql asp.net stored-procedures asynchronous asp-classic

我正在尝试将控制面板写入

  1. 告知某些KPIS
  2. 通过按下按钮然后在数据库上运行存储过程或设置特定设置等,使用户能够初始化某些请求/作业
  3. 到目前为止,非常好,除了我想运行一些更大的工作,其中运行的作业时间长度未知,并且可以在脚本超时期间和用户愿意等待的时间内运行回应。

    我想要的是一个“即发即弃”的过程,以便用户点击按钮,即使他们杀死了页面或关闭手机,他们也知道作业已经启动并将完成。

    我正在查看C#BeginExecuteNonQuery,它是对查询的异步调用,因此触发了proc,但控件不必等待它的响应继续进行。但是我不知道触发它的页面/应用程序关闭后会发生什么。

    此外,我正在考虑某种类型的Ajax命令,它在后台激活页面中的代码,因此用户不知道它正在运行但是我相信如果用户关闭页面,脚本将会死亡,该命令也会在服务器上死掉。

    我所知道的唯一方法是“队列”表,其中将作业插入此表中,然后每隔一两分钟就会发出一个MS代理作业,检查新插入,然后运行代码(如果有的话)。这样一切都在数据库上,只有数据库崩溃会破坏它。它不会帮助同时运行的多个作业需要花费很长时间,但是我唯一可以肯定的是确保代码运行。

    有什么想法吗?

    任何语言都可以。

3 个答案:

答案 0 :(得分:1)

由于Web浏览器未连接,因此来自总是的请求需要花费大量时间。管理因素不是浏览器的作用,而是网站本身允许行动持续多长时间。

IIS(通常是Web服务器)具有请求的超时期限,如果正在完成的工作花费的时间太长,则请求将终止。这将涉及突然停止任何花费这么长时间的事情,例如数据库调用,运行代码等等。

简单地使长时间运行的操作异步似乎是一个好主意,但我建议不要这样做。原因是在ASP和ASP.Net中,异步调用的代码仍然以一种阻止其他合法请求通过的方式消耗线程(在某些情况下,你最终可能会占用两个线程!)。这可能会以非显而易见的方式产生影响。最好只增加超时并允许同步阻塞任务完成。要完全完成此类请求,您无需做任何特殊处理,即使发件人关闭浏览器或立即关闭手机(假设已收到整个请求),也会发生这种情况。

如果您仍然担心完成某项工作,无论Web请求发生了什么,那么创建一个进程外服务器/服务可能会更好工作和可以交付这些任务。然后,您的网站会调用一个方法,该方法在服务内部启动自己的异步线程来完成工作,然后立即返回。也许它还会返回一个请求ID,以便网页可以稍后通过其他方法检查所请求工作的状态。

答案 1 :(得分:0)

您可以使用异步方法并从此方法调用查询。 您可以通过以下方式将简单方法更改为异步方法。

考虑您要异步调用Test方法 -

     Class AsynchDemo
     {       
            public string TestMethod(out int threadId) 
            {

              //call your query here
            }

           //create a asynch handler delegate: 

           public delegate string AsyncMethodCaller(out int threadId);
     }

在您的主程序/或您必须调用测试方法的地方:

     public static void Main() 
     {

        // The asynchronous method puts the thread id here. 
        int threadId;

        // Create an instance of the test class.
        AsyncDemo ad = new AsyncDemo();

        // Create the delegate.
        AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

        // Initiate the asychronous call.
        IAsyncResult result = caller.BeginInvoke( 
            out threadId, null, null);


        // Call EndInvoke to wait for the asynchronous call to complete, 
        // and to retrieve the results. 
        string returnValue = caller.EndInvoke(out threadId, result);

        Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
            threadId, returnValue);

   }

答案 2 :(得分:0)

根据我的经验,即使客户端断开连接,经典ASP或ASP.NET页面也会一直运行,除非您有适当的位置来检查客户端是否仍然连接,如果不是,则执行某些操作,或者超时到了。

但是,将这些类型的作业按计划任务运行可能会更好。

提交网页时,可以在数据库中记录需要运行的任务,然后在计划任务运行时检查并启动作业。

许多Web主机和/或Web控制面板允许您创建按计划调用URL的计划任务。

或者,如果您可以直接访问Web服务器,则可以在服务器上创建计划任务以按计划调用URL。

或者,如果是ASP.NET,您可以在global.asax中放置一些代码以按计划运行。但请注意,如果您的网站在一段时间不活动后设置为停止,那么除非频繁进行连续活动,否则这将无效。