3

I'd like to submit my form and then let it go to another page (telling the user that they'll receive an email when it's finished) while running the stored procedure (SQL) in the background.

I don't want the user to wait 30 mins for the search to complete and then go to the other page. How can I accomplish this?

// Clicking on the Search button    
protected void btnSearch_Click(object sender, EventArgs e)
{
    Guid SearchGUID;
    SearchGUID = Guid.NewGuid();

    Hashtable htSearch = new Hashtable();
    htSearch["value"] = 2;

    // Run the stored procedure (takes 30 mins)
    objSmart.RunSearch(htSearch);

    // Redirect to the other page
    Response.Redirect("Search.aspx?search=" + SearchGUID.ToString());
}
Charles Xavier
  • 1,015
  • 3
  • 14
  • 33
  • 2
    I would fire a message to a distributed system that monitors a message queue, for instance, that is purpose built for the task. Long running tasks, even if done as fire-and-forget, are not appropriate for asp.net which is intended for use as request/response. – Crowcoder Aug 13 '18 at 17:31

2 Answers2

6

If your background task were going to take only 30~90 seconds, it could be handled with Async, the thread pool/Tasks library, or any number of other solutions. But once it starts taking several minutes, or in your case, 30+ minutes, you need a more robust out-of-process solution. ASP.NET's architecture is just not designed for long-running background threads. IIS will recycle your application pool/domain at random intervals to optimize resource usage, and while it will try its best to let your threads finish, that's not guaranteed. See Scot Hanselman's blog post on this subject for some background and suggestions.

Here are a few solutions that you could consider, depending on your application constraints:

  • If you're using MS SQL Server, you might be able to encapsulate the stored procedure and the completion email in a SQL Agent Job that you kick off from your web app. (You can even run .NET code in SQL Server, although it's not pretty.)
  • You could write a true background process to run as an EXE and be hosted in Windows Task Scheduler. Your web app can manually kick off this task, e.g. C# start a scheduled task.
  • You could use a third-party background tasking/queuing framework like https://www.hangfire.io/.
Jordan Rieger
  • 3,025
  • 3
  • 30
  • 50
  • Yes. Also could use a windows service. This is an executable that runs on a schedule. I've used in the past to read a 'jobs' table and then kick off the long-running process. We would notify the user via an email message when complete. – JazzmanJim Aug 13 '18 at 19:34
  • Personally, even 30-90 seconds is still too long for Async or thread pool/Task in ASP.NET. I’ve used short-lived Jobs in SQL Server before, but now I think a messaging queue with Windows Service is ideal. – alans Aug 13 '18 at 23:14
  • @alans The default ASP.NET script timeout is 90 seconds, so that's a good indication that operations taking up to 90 seconds will be OK in the IIS request/response thread pool. This suggests that a background thread kicked off from a web page would almost certainly live up to 90 seconds. But you're right, it's always going to be safer to use an out-of-process solution. It just might be overkill in a lot of cases. – Jordan Rieger Aug 13 '18 at 23:27
0

You need to run the method async, as mentioned here.

This will call the method then go to the next item.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
berr08
  • 236
  • 1
  • 16
  • 2
    No. Do not run a 30 minute process in asynch. IIS is not designed for long running processes. IIS can recycle your app pool and the thread might not finish. – JazzmanJim Aug 13 '18 at 19:31