tobiak777
tobiak777

Reputation: 3365

WebJob dramatically slows my website down

I have the following WebJob :

    static void Main(string[] args)
    {

        Bootstrap(); //IoC container config

        System.Diagnostics.Trace.TraceInformation("Entering the main loop");
        while (true)
        {
            OrdersFetcher.DoWork();
        }
    }

    public static class OrdersFetcher
    {
        const int MINIMUM_NUMBER_OF_SECONDS_BETWEEN_FETCHES = 10;
        static DateTime _lastFetchDate = DateTime.UtcNow.AddSeconds(int.MinValue);
        static bool _currentlyRunning = false;

        public static void DoWork()
        {
            if (DateTime.UtcNow - _lastFetchDate < TimeSpan.FromSeconds(MINIMUM_NUMBER_OF_SECONDS_BETWEEN_FETCHES))
                return;

            if (_currentlyRunning)
                return;

            _currentlyRunning = true;
            _lastFetchDate = DateTime.UtcNow;
            Task.Factory.StartNew(() => { FetchOrders(); }).ContinueWith((task) =>
            {
                _currentlyRunning = false; Console.WriteLine("**** Orders Fetching Ended ****");
            });

        }

        private static FetchOrders()
        {
            var db = Program.container.Resolve<MyDbContext>();
            //Fetch from third party and add changes to DbContext
            db.SaveChanges();
            db.Dispose();
        }
    }

The WebJob is configured to be a Singleton.

I use Unity and my LifetimeManager for the DbContext is the PerThreadLifetimeManager. For all other types (which are simple classes not requiring any kind of dispose) a new instance is created every time.

I've just check and the memory consumption is ok but the CPU usage is 100%. Why is that and how can I fix it ?

Upvotes: 1

Views: 166

Answers (2)

Ryan Kekos
Ryan Kekos

Reputation: 66

You need to sleep your thread between repeating calls.

Upvotes: 1

serhiyb
serhiyb

Reputation: 4833

Try:

if (DateTime.UtcNow - _lastFetchDate < TimeSpan.FromSeconds(MINIMUM_NUMBER_OF_SECONDS_BETWEEN_FETCHES))
                Thread.Sleep((long)DateTime.UtcNow.Substract(_lastFetchDate). TotalMilliseconds);

instead of:

if (DateTime.UtcNow - _lastFetchDate < TimeSpan.FromSeconds(MINIMUM_NUMBER_OF_SECONDS_BETWEEN_FETCHES))
                return;

This way your thread will leave CPU do other stuff instead of immediately retrying.

Upvotes: 5

Related Questions