Raj
Raj

Reputation: 361

Why C# thread stop working automatically

I have a thread in my program which runs the timer function for example

Thread PopMonitoringThread = new Thread(new ThreadStart(PopMonitoring));  
PopMonitoringThread.Start();

public static void PopMonitoring()
{
    TimerCallback callback = new TimerCallback(Tick);
    Timer stateTimer = new Timer(callback, null, 0, 1000);
}

//Timer method
static public void Tick(Object stateInfo)
{
    try
    {
        if (Properties.Settings.Default.BatchingMode > 0)
        {
            if (batchTime.Subtract(DateTime.Now) < TimeSpan.Zero)
            {
                batchTime = DateTime.Now.AddMinutes(Properties.Settings.Default.BatchingMode);
                Console.WriteLine("-----------------------------------------------------");
                Process();
                Console.WriteLine("Batch Process Run");
                Console.WriteLine("-----------------------------------------------------");
            }
            Console.WriteLine("{0}", DateTime.Now.ToString("h:mm:ss"));
        }
        Console.WriteLine("Pop3 Monitoring start after: {0}", batchTime.Subtract(DateTime.Now));
    }
    catch (Exception e)
    {
        throw e;
    }
}

When I comment out my Process() method it works fine every second my timer interation works but when I uncomment Process method from my Tick method timer stops working ie Tick method stops working. Process method code is working perfect mean there are no compile and runtime errors.

Upvotes: 2

Views: 1829

Answers (1)

Thorarin
Thorarin

Reputation: 48476

The thread you are creating stops almost instantly, whether or not you're calling Process(). All you are doing in the thread, is starting a timer. the actual Tick method is being executed in a background thread from the Thread Pool.

Now, at some point your stateTimer will be garbage collected, because it has fallen out of scope. At this point the timer will no longer be triggered. Most likely, this garbage collection is happening much sooner when you are calling Process()

You can test it by calling GC.Collect() in your Tick method. You'll see it stops after one or two ticks.

To fix it, make stateTimer a member variable. Lose the Thread stuff:

class Program
{
    private static Timer _stateTimer;

    static void Main(string[] args)
    {
        _stateTimer = new Timer(Tick, null, 0, 1000);
        Console.ReadLine();
    }

    static public void Tick(Object stateInfo)
    {
        // ...
    }
}

PS: I assume this code is because you've been experimenting, but if you want to rethrow an exception you've caught, you should use throw; without any parameters: see this Blog article for a brief explanation.

Upvotes: 3

Related Questions