Hugo Carvalho
Hugo Carvalho

Reputation: 11

Azure WebJob with queues and System.Threading.Timer

I'm using Azure WebJob to get messages from a service bus queue with success. But i wanted to use this same WebJob to run some methods every 5 seconds.

I've tried the following approach, and locally it run fine, but when i publish it only runs once. No errors on azure logs.

What am i doing wrong?

Thanks for helping.

   static void Main()
    {
        try
        {

    var testTimer = new System.Threading.Timer(e => TestMethod(), null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(5));

            SetupJobHost();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }

     private static void TestMethod()
    {
        Console.WriteLine("Test");
    }

Upvotes: 1

Views: 347

Answers (2)

Rob Reagan
Rob Reagan

Reputation: 7696

I recommend taking a different approach and using a TimerTrigger. You can use a simple chron expression that will cause your method to be executed on a set schedule. If you go this route, make sure that you deploy your WebJob as a triggered job (not continuous!) and that you call the JobHostConfiguration's UseTimers() method before calling the JobHost's RunAndBlock method. This is a much easier and cleaner approach than rolling your own timer service.

Upvotes: 1

Jambor - MSFT
Jambor - MSFT

Reputation: 3293

According to your description, I have tested your code and reproduced on my side.

After some trials, I found a problem with the class System.Threading.Timer, if we don’t refer to the Timer instance after the initial assignment, then it will get garbage collected.

Please try below methods to see whether it helps:

Method 1: Deploy your webjob in Debug Mode without changing any code;

Method 2: Change your code as follows and deploy it to Azure in Release Mode.

try
{
    var testTimer = new System.Threading.Timer(e => TestMethod(), null, TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(5));
    SetupJobHost();
    testTimer.Dispose();
}
catch (Exception ex)
{
    Console.WriteLine(ex);
}

I recommend you to read this article for a better understanding of this interesting issue. In addition, you could achieve your purpose by using the following code:

System.Timers.Timer sysTimer = new System.Timers.Timer(TimeSpan.FromSeconds(5).TotalMilliseconds);
sysTimer.Elapsed += (s, e) =>TestMethod();
sysTimer.Enabled = true;

Upvotes: 0

Related Questions