System.Threading.Timer in C# It Seems to Be Not Working. It Runs Very Fast Every 3 Second

System.Threading.Timer in C# it seems to be not working. It runs very fast every 3 second

This is not the correct usage of the System.Threading.Timer. When you instantiate the Timer, you should almost always do the following:

_timer = new Timer( Callback, null, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );

This will instruct the timer to tick only once when the interval has elapsed. Then in your Callback function you Change the timer once the work has completed, not before. Example:

private void Callback( Object state )
{
// Long running operation
_timer.Change( TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
}

Thus there is no need for locking mechanisms because there is no concurrency. The timer will fire the next callback after the next interval has elapsed + the time of the long running operation.

If you need to run your timer at exactly N milliseconds, then I suggest you measure the time of the long running operation using Stopwatch and then call the Change method appropriately:

private void Callback( Object state )
{
Stopwatch watch = new Stopwatch();

watch.Start();
// Long running operation

_timer.Change( Math.Max( 0, TIME_INTERVAL_IN_MILLISECONDS - watch.ElapsedMilliseconds ), Timeout.Infinite );
}

I strongly encourage anyone doing .NET and is using the CLR who hasn't read Jeffrey Richter's book - CLR via C#, to read is as soon as possible. Timers and thread pools are explained in great details there.

System.Threading.Timer does not work correctly

I just post what found here for people that have problem like me.
I found the answer from another thread.
I use "HighResolutionTimer.cs" and it works perfect:
https://gist.github.com/DraTeots/436019368d32007284f8a12f1ba0f545

System.Threading.Timer call drifts a couple seconds every day

None of the timers in the .NET Framework will be accurate. There are too many variables in play. If you want a more accurate timer then take a look at multimedia timers. I have never used them over longer durations, but I suspect they are still substantially more accurate than the BCL timers.

But, I see no reason that would prohibit you from using the System.Threading.Timer class. Instead of specifying TimeSpan.FromDays(1) use Timeout.Infinite to prevent periodic signaling. You will then have to restart the timer, but you can specify 23:59:58 or 1.00:00:05 for the dueTime parameter depending on what you calculate the next due time to be to have signal at 2:00a.

By the way, the System.Timers.Timer will do no better than System.Threading.Timer. The reason is because the former actually uses the later behind the scenes anyway. System.Timers.Timer just adds a few handy features like auto resetting and marshaling the execution of the Elapsed onto an ISynchronizeInvoke hosted thread (usually a UI thread).

System.Threading.Timer with WPF/C# problems

Don't use local variable for the timer, timer will be disposed after TimerMetod ends, timer must be a class member.

Use DispatcherTimer. For WPF this is better option than System.Threading.Timer

Threading.Timer calls delegate on non-UI thread unlike DispatcherTimer. This could be issue when you code interacts with UI.

public partial class MainWindow : Window
{
private readonly DispatcherTimer _dispatcherTimer;
private int _count;

public MainWindow()
{
_dispatcherTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(1)
};
_dispatcherTimer.Tick += OnTimer;

InitializeComponent();
}

private void OnTimer(object source, EventArgs e)
{
_count++;
text.Text = "Count:" + _count;
}

private void Button_Click(object sender, RoutedEventArgs e)
{
_dispatcherTimer.Start();
}
}

XAML Code

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Start Timer" Click="Button_Click"></Button>
<TextBlock Grid.Row="1" x:Name="text"></TextBlock>

</Grid>

Problems with System.Timers.Timer. Firing more than once occasionally

what I suspect is that Initialize is called multiple time, what you could do is check that the _databaseBackupTimer is null before creating a new instance

if it's not null, just skip the whole code in that method

C# Timer firing too early

Setup your timer so that you aren't creating a new instance with every timer tick. In the example below, I've disabled AutoReset so that we can set a new interval and start the timer again manually.

    static Timer timer;
static Random random = new Random();
public static void random_Start()
{
timer = new Timer(random.NextDouble()*10000+5000);
timer.Elapsed += OnTimedEvent;
timer.AutoReset = false;
timer.Start();
Console.WriteLine("Start");
}

private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
Console.WriteLine("Tick");
timer.Interval = random.NextDouble()*10000+5000;
timer.Start();
}

call a method only in 30th and 0th second of every minute c#

One simple way to solve it using a timer is to set the interval to a single second, and in the timer's callback method to check if the value of DateTime.Now.Seconds divides by 30:

void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(DateTime.Now.Seconds % 30 == 0)
{
CalculateItems();
}
}

Why does a System.Timers.Timer survive GC but not System.Threading.Timer?

You can answer this and similar questions with windbg, sos, and !gcroot

0:008> !gcroot -nostacks 0000000002354160
DOMAIN(00000000002FE6A0):HANDLE(Strong):241320:Root:00000000023541a8(System.Thre
ading._TimerCallback)->
00000000023540c8(System.Threading.TimerCallback)->
0000000002354050(System.Timers.Timer)->
0000000002354160(System.Threading.Timer)
0:008>

In both cases, the native timer has to prevent GC of the callback object (via a GCHandle). The difference is that in the case of System.Timers.Timer the callback references the System.Timers.Timer object (which is implemented internally using a System.Threading.Timer)

Replace Thread.Sleep with System.Threading.Timer?

The idea is to have a timer and Enable it when you want to set the delay in your program:

System.Timers.Timer Delay = new System.Timers.Timer();
Delay.Elapsed += new System.Timers.ElapsedEventHandler(Delay_Elapsed);
Delay.Interval=Convert.ToInt32(milliseconds);
Delay.Enabled = false;

void Delay_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Delay.Enabled = false;
}
......
.....
if (nextTimeRead > now) //Yes, so wait 7 minutes for files to be available
{
TimeSpan span = nextTimeRead.Subtract(now);
Double milliseconds = span.TotalMilliseconds;
Console.WriteLine("Sleep for milliseconds: " + milliseconds.ToString());
Delay.Enabled = true;
while (Delay.Enabled)
{
////Wait until time passes
}
Console.WriteLine("Download files after sleep of: " + nextTimeRead.ToString());
DownloadFilesByPeriod(nextTimeRead);
}


Related Topics



Leave a reply



Submit