Why Does System.Threading.Timer Stop on Its Own

Why does System.Threading.Timer stop on its own?

If you need a timer on a Windows Form then drop a System.Windows.Forms.Timer onto the form - there's no reason to use a System.Threading.Timer unless you need better resolution than 55 ms.

The reason the timer "stops" is because it's being garbage-collected. You're allowing it to go out of scope in the Form1_Load method because you only declare it as a local variable. In order to keep the timer "alive", it needs to be a private field on the form class so that the GC knows it's still needed.

In other words:

public partial class Form1 : Form
{
private System.Threading.Timer testTimer;

...

public void Form1_Load(object sender, EventArgs e)
{
TimerCallback timerDelegate = new TimerCallback(tick);
testTimer = new System.Threading.Timer(timerDelegate, null, 1000, 1000);
}
}

But again, in this case it's simplier to use System.Windows.Forms.Timer, which is an actual component in the toolbox that you can just drop onto the form.


Edit - As the comments now reveal, if this is just a test app and the real application is in a Windows Service, you cannot use System.Windows.Forms.Timer for that. Just remember not to let your System.Threading.Timer go out of scope.

C# Timer getting stopped after some time

Could it be that the Timer gets disposed by the GarbageCollector? It seems like you only declare the variable holding the Timer-Reference in a local scope.

To prevent GarbageCollection, make sure that the Timer-Reference gets stored in an Object that exists for the entire lifetime of the Service.

See this post for a similar issue: Why does System.Threading.Timer stop on its own?

System.Threading.Timer stops the thread?

Your code works, you used the best Timer in my mind (System.Threading).
There isn't problem to re-execute the same method even if previous call isn't finished. The previous instance isn't killed.
You just have to manage the reentrancy, but the way you did it prevents problems (your timer fires each hour so there is no threading problem between the line which checks 'LastCheckDateTime' and the line which change its value).

I tried the following which works well: the event is fired every second but the "Process" starts by a 3s wait.

 public partial class MainWindow : Window
{
private System.Threading.Timer _timer;

public MainWindow()
{
InitializeComponent();
_timer = new Timer(new System.Threading.TimerCallback(Process), null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
}

private void Process(object state)
{
DateTime dt = DateTime.Now;
System.Threading.Thread.Sleep(3000);
Debug.WriteLine("dt=" + dt.ToString("HH:mm:ss.fff") + " Now=" + DateTime.Now.ToString("HH:mm:ss.fff"));

}

}

Best regards,

How to stop a System.Threading.Timer and cancel any callback that is running?

According to the documentation, you should use the Dispose(WaitHandle) overload:

Releases all resources used by the current instance of Timer and signals when the timer has been disposed of.

When this method completes, it signals the WaitHandle specified by the notifyObject parameter.Use this overload of the Dispose method if you want to be able to block until you are certain that the timer has been disposed. The timer is not disposed until all currently queued callbacks have completed.

void Dispose()
{
timer.Change(Timeout.Infinite, Timeout.Infinite); //Stop timer

var waiter = new ManualResetEvent(false);
timer.Dispose(waiter);
waiter.WaitOne();
waiter.Dispose();

timerSync.Dispose();
//Dispose other things...
}

If you don't want to wait for the current callback to be executed at all, you could follow the IDisposable pattern:

Timer timer = new Timer(Timer_Tick, null, Timeout.Infinite, Timeout.Infinite);
Mutex timerSync = new Mutex();
private bool _disposed;

void Dispose()
{
_disposed = true;
...
}

void Timer_Tick()
{
if (_disposed)
{
return;
}

...
}

Is it possible to stop a threading.Timer immediately?

This is a "feature" of the Timer. The callback may run on a different thread and it does not even need to terminate before it is called again (for example if its execution takes more that 1000 ms). If you don't need this feature and it is OK to run the callback 1000 ms after the termination of the previous callback you can just avoid passing the period parameter and restart the timer manually at the end of the callback.

Can I stop a System.Threading.Timer

There is no way to know the Thread on which a Threading.Timer callback will run ahead of time. Hence there is no general way to abort it. It is possible to have the callback itself communicate the Thread instance but it opens up a couple of race conditions

Note: In general using Abort is a bad practice. It's a fairly reliable way to end up with hard to detect deadlocks and / or resource leaks. It's much better to use a passive mechanism like CancellationToken

How to STOP a System.Threading.Timer

I need to know how I can stop a System.Threading.Timer because when they order a taxi, cancel it after lets say 8 seconds then straight after they order another taxi, that taxi takes 2 seconds to come not 10 so it still uses the old taxi timer, how do I stop it?

Take a step back. You don't have to worry about canceling a timer if you never make one.

You are describing an asynchronous workflow with cancellation. C# and the .NET framework already has this feature, so use it rather than trying to roll your own.

Make an async workflow method that awaits a Task.Delay task that takes a CancellationToken. The continuation of the delay is the arrival of the taxi; the cancellation method causes the task to fail by canceling the token.

There is plenty of documentation on this mechanism, so start reading it. A good place to start is here:

https://msdn.microsoft.com/en-us/library/dd997364

Does System.Threading.Timer rely on system time being correct?

I can't replicate a scenario that results in this.

Using this code

class Program
{
private static Timer timer;
private static readonly Stopwatch stopwatch = new Stopwatch();

static void Main(string[] args)
{
timer = new Timer(Tick);
stopwatch.Start();
timer.Change(30000, Timeout.Infinite);
Console.ReadLine();
}

private static void Tick(object obj)
{
stopwatch.Stop();
Console.WriteLine(stopwatch.Elapsed.Seconds);
}
}

I start the app, change my local computer time to 20 seconds in the future. The Tick method is still called 30 seconds after I started the app. The stopwatch says 30 and my mobilephone timer says 30.



Related Topics



Leave a reply



Submit