Launching a long-running background task - from AS

2020-07-22 16:34发布

问题:

I have a fairly long-running process (several minutes) that I need to run roughly once a month - but not on a fixed schedule, but after a user clicks Go in a ASP.NET Webforms GUI page.

Since ASP.NET really isn't designed to handle long-running background tasks, my idea was to put this into a separate console app. But how to launch that as needed?

What happens if I use Process.Start(....) from my ASP.NET page's code-behind? I would like to avoid blocking the whole Web UI for 20 minutes or so... and also: even if it doesn't block my UI, what happens to my long-running task if the ASP.NET app pool recycles while it's still running?

Another idea was to have a frequently running job (runs every 2 minutes) check for some kind of a flag (e.g. existence of some database entries), and if needed, that job would then launch the long-running task.

But the same question: if I launch my 20-minute task from a job using Process.Start() - does that block the caller?

It seems like a bit of overkill to schedule that long running tasks five times a day since it typically is run only once a month - but at the same time, the user expects to have his results within a reasonable amount of time (less than 1 hour, if ever possible) after scheduling the process - so I cannot really just schedule it to run once at night either ...

回答1:

First off - for several reasons - ASP.NET is imho not the solution for long-running tasks/jobs/... whatsoever.

I have had this requirement a lot of times, and always solved/separated it like:

Worker
A service with

  • Quartz.net (for scheduling and processing, even if you don't have a specific timestamp for execution - but the overall handling in this framework is simply superb)
  • a persistent job-store (to handle start/stop and completed/aborted/paused jobs)
  • eg ServiceStack as the interop between the two processes

Website
Simply calls some webservice-methods of the worker to enqueue/query/pause/stop/... a job. For querying jobs a call to a unified job-store might be an option (eg. db)

It might be a bit of an overkill for you though ... but this is my Swiss army knife for such scenarios.



回答2:

Hangfire is what you are looking for. Best part is it comes with a built in dashboard.

You might have to write some logic on the top of it.

You can find it here. http://hangfire.io/



回答3:

Use the standard built-in Windows Task Scheduler like you have done, but invoke it from your web application.

Configure your task in Task Scheduler. It does not need to have a scheduled trigger. From your web application, just use Process.Start to kick it off:

SchTasks.exe /Run /TN Folder\Taskname

I have not used SchTasks.exe directly, but have used the Microsoft.Win32.TaskScheduler wrapper classes.