[ACCEPTED]-How should I perform a long-running task in ASP.NET 4?-azure-webjobs

Accepted answer
Score: 18

Preferentially, avoid having long tasks 17 executing in such an environment.

Delegate 16 long running tasks out to a stable system 15 service via interoperability, leaving the 14 web application responsive and only required 13 for direct user requests.

Web applications 12 have never been (and still aren't) considered 11 reliable systems - anyone who has ever used 10 a browser has encountered (at least) a time-out, to 9 be sure; and such inconvenience (for both 8 parties) is not limited to this scenario. Of 7 course, any system can crash, but the circumstances 6 surrounding such an event on a system built-to-be-persistent ought 5 to completely exceptional.

Windows services 4 are designed to be long running, and if 3 something goes wrong you've generally got 2 more to worry about than your individual 1 service.

Score: 3

It's best to be avoided, but if you are 6 forced to, consider Hanselman's thoughts 5 at How to run Background Tasks in ASP.NET.

Among them, and for something quick 4 and easy, I would suggest you look in particular 3 at the QueueBackgroundWorkItem added in 4.5.2.

From personal experience, Task 2 does not cut it. QueueBackgroundWorkItem 1 is much better.

Score: 0

My preferred method is the same as Robert 6 Harvey proposes in his answer.

You can still 5 use the Task Parallel Library, but spin the task up in a separate 4 process outside of IIS (the reason being 3 that IIS has a limited number of worker 2 threads to hand out and imposes other limitations 1 that can make long running tasks unpredictable).

Score: 0

You can create a static ThreadPool like 4 this http://www.dotnetperls.com/threadpool with limited threads number(for example 3 only 2). and then queue tasks in it, but 2 it's highly not recommended because web 1 servers are not for such kind of tasks

Score: 0

This is a description of a 'once a day' scenario.

If 14 you really want to avoid creating a service, you 13 could start a timer with 1 minute intervals. Each 12 time the timer delegate is invoked, you 11 will have to run something like this (pseudo 10 code):

lastInvokeDay = LoadLastInvokeDate();
If (lastInvokeDay < DateTime.Now.Date && timeOfDayToRun == DateTime.Now.Time)
    today = DateTime.Now.Date;
    lastInvokeDay = today;

Keep in mind that the lastInvokeDay 9 should be persisted either in Database or 8 on a file...

Now, If you want to enable 7 immediate invocation of the task, you could 6 simply call runMyTask() on demand. If its important 5 for you to keep the runMyTask from occuring 4 more than once a day, you could create a 3 syncronized block of code inside it (with 2 a lock statement) and move the lastInvokeDay check inside.

Does 1 this answer your question?

Score: 0

I could suggest a simple solution, which 18 doesn't use Windows Services, yet is able 17 to invoke a task to be executed outside 16 of the IIS sandbox. Also it could be easily 15 adopted by any other language or mix of 14 them, in my case that was Python

  1. Create Event 13 log and source on the IIS server (requires 12 Administrative rights), executing from the 11 PowerShell console:

    [System.Diagnostics.EventLog]::CreateEventSource('Automations', 'Automations')

    If you have no Administrative 10 rights, skip this step. You will fallback 9 to use Windows/Application log

  2. Create a Task 8 Scheduler task to be executed on event, for 7 example, with ID = 2020, Log = 'Automations' and 6 Source = 'Automations'. There you could 5 invoke whatever you like with all necessary 4 permissions

  3. Prepare a code to send your event, while 3 handling a web request. Giving you a Python 2 example, but you could adopt it to your 1 language:

    import win32evtlog
    app_name = "Automations"
    event_id = 2020
    event_category = 0
    event_type = win32evtlog.EVENTLOG_INFORMATION_TYPE
    messages = ['Starting automation']
    # Logs event into the custom Automations log if it exists,
    # otherwise logs event into Windows/Application log
    handle = win32evtlog.OpenEventLog("localhost", app_name)
    win32evtlog.ReportEvent(handle, event_type, event_category, event_id, None, messages, None)
  4. Profit

More Related questions