Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using webbackgrounder nuget in MVC to run background task for long time

I need to implement a task in background so what is my task? I have a table that stores the rent amount of each customers, so I need to calculate the rent price in each month after a specific datetimeackf so I googled it and I found a piece of code that (it is nuget called webbackgrounder) I added it to my solution and it gives me this part of code to handle my task:

using System;
using System.Threading;
using System.Threading.Tasks;

    namespace WebBackgrounder.DemoWeb
    {
        public class SampleJob : Job
        {
            public SampleJob(TimeSpan interval, TimeSpan timeout)
                : base("Sample Job", interval, timeout)
            {
            }

            public override Task Execute()
            {
                return new Task(() => Thread.Sleep(3000));
            }
        }
    }

I want to know how can I program my task ?

More details : Here

I found this article but in fact I don't know can I use this method for longtime ?? Best regards .

any ideas will be appreciated.

like image 627
Ehsan Akbar Avatar asked Sep 19 '14 08:09

Ehsan Akbar


Video Answer


2 Answers

You need to also add in a class to the App_Start folder of your application that will start the Job and manage it's lifetime. You can see an example here... https://github.com/NuGet/WebBackgrounder/tree/master/src/WebBackgrounder.DemoWeb

Here is the code from the demo app

using System;
using Elmah;
using WebBackgrounder.Jobs;

[assembly: WebActivator.PostApplicationStartMethod(typeof(WebBackgrounder.DemoWeb.App_Start.WebBackgrounderSetup), "Start")]
[assembly: WebActivator.ApplicationShutdownMethod(typeof(WebBackgrounder.DemoWeb.App_Start.WebBackgrounderSetup), "Shutdown")]

namespace WebBackgrounder.DemoWeb.App_Start
{
    public static class WebBackgrounderSetup
    {
        static readonly JobManager _jobManager = CreateJobWorkersManager();

        public static void Start()
        {
            _jobManager.Start();
        }

        public static void Shutdown()
        {
            _jobManager.Dispose();
        }

        private static JobManager CreateJobWorkersManager()
        {
            var jobs = new IJob[]
            {
                new SampleJob(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(20)),
                /* new ExceptionJob(TimeSpan.FromSeconds(15)), */
                new WorkItemCleanupJob(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(5), new WorkItemsContext())
            };

            var coordinator = new WebFarmJobCoordinator(new EntityWorkItemRepository(() => new WorkItemsContext()));
            var manager = new JobManager(jobs, coordinator);
            manager.Fail(ex => Elmah.ErrorLog.GetDefault(null).Log(new Error(ex)));
            return manager;
        }
    }
}

However I found it simpler to just use the parts of Webbackgrounder that I needed as follows. Place this class in the App_Start folder

using System;
using BombaySapphireCds.Jobs;
using Elmah;

[assembly: WebActivator.PostApplicationStartMethod(typeof(BombaySapphireCds.App_Start.PodMonitorConfig), "Start")]
[assembly: WebActivator.ApplicationShutdownMethod(typeof(BombaySapphireCds.App_Start.PodMonitorConfig), "Shutdown")]

namespace BombaySapphireCds.App_Start
{
    public static class PodMonitorConfig
    {
        private static PodMonitorJob m_job;

        public static void Start()
        {
            m_job = new PodMonitorJob(TimeSpan.FromSeconds(20));
        }

        public static void Shutdown()
        {
            m_job.Dispose();
        }
    }
}

and the class to do the actual work... (put this anywhere you like)

using System;
using System.Threading;
using System.Threading.Tasks;

namespace BombaySapphireCds.Jobs
{
    public class PodMonitorJob : IDisposable
    {
        private CancellationTokenSource m_cancel;
        private Task m_task;
        private TimeSpan m_interval;
        private bool m_running;

        public PodMonitorJob(TimeSpan interval)
        {
            m_interval = interval;
            m_running = true;
            m_cancel = new CancellationTokenSource();
            m_task = Task.Run(() => TaskLoop(), m_cancel.Token);
        }

        private void TaskLoop()
        {
            while (m_running)
            {
                //
                // Do monitoring work here.
                //

                Thread.Sleep(m_interval);
            }
        }

        public void Dispose()
        {
            m_running = false;

            if (m_cancel != null)
            {
                try
                {
                    m_cancel.Cancel();
                    m_cancel.Dispose();
                }
                catch
                {
                }
                finally
                {
                    m_cancel = null;
                }
            }
        }
    }
}
like image 81
David Ritchie Avatar answered Oct 30 '22 11:10

David Ritchie


This has become the new standard for background task execution on the web. It's a NuGet package and it's called HangFire - https://github.com/HangfireIO/Hangfire. The tasks persist even beyond apppool recycling.

like image 40
Kind Contributor Avatar answered Oct 30 '22 13:10

Kind Contributor