M
m00n
Guest
Hi all…
I wanted to create a timer that could app where I could monitor how many times a timer will tick per second. This all came about because I wanted to be able to throttle down how many times I was sending things over a network stream and I wanted to find the sweet spot in milliseconds and using a timer. Think FPS.
To do this I used two System.Timers.Timer objects.
_tpsTimer (ticks per second)
_oneSecondTimer
I wrote a couple versions of the app. The logic behind these two apps are identical except for the fact that one is a winform one is a console. The two versions I’m most interested in posting about are
I was surprised at how much of a difference there was in ticks per second between a console app and windows form app. Is there REALLY that much overhead in a windows form app? Secondly, am I way off base in using timers for this purpose? Ultimately wanting to create a FPS throttle... How many images I send over a network per second.
The following image shows various tests at different millisecond intervals. The columns are :
Here is the code for the console app.
using System;
namespace SystemTimersConsole
{
class Program
{
// Ticks on 1 second intervals, Used to write _tpsCount every second
private System.Timers.Timer _oneSecondTimer;
// Ticks on user specified interval, used to update _tpsCount variable
private System.Timers.Timer _tpsTimer;
// Represends how many times in 1 second _tpsTimer is fired off.
private int _tpsCount;
// Since timers run in differnt treads than GUI thread, need a delegate to
// update the GUI
public delegate void DisplayTPS( object source, System.Timers.ElapsedEventArgs e );
static void Main( string[ ] args )
{
Program p = new Program();
p.Reset( );
// Param specifies millisecond frequency for _tpsTimer
p.StartTimers( 19 );
ConsoleKeyInfo i = Console.ReadKey( );
}
/// <summary>
/// _oneSecondTimer tick event.
/// Updates the list box with the TPS count information. Function can be called from either
/// the GUI thread or one one of timer threads.
/// </summary>
/// <param name="state">Not using this state</param>
private void DisplayData( Object source, System.Timers.ElapsedEventArgs e )
{
Console.WriteLine( "TPS COUNT : " + _tpsCount );
_tpsCount = 0;
}
/// <summary>
/// _tpsTimer tick event handler. Increments the TPS counter indicator.
/// </summary>
/// <param name="state"></param>
private void IncTPSCount( Object source, System.Timers.ElapsedEventArgs e )
{
_tpsCount++;
}
/// <summary>
/// Resets all the controls and what not.
/// </summary>
private void Reset( )
{
if( _oneSecondTimer != null )
_oneSecondTimer.Dispose( );
if( _tpsTimer != null )
_tpsTimer.Dispose( );
_oneSecondTimer = null;
_tpsTimer = null;
_tpsCount = 0;
}
/// <summary>
/// Resets controls, timers and restarts timers.
/// </summary>
/// <param name="milli">Specifies in milliseconds how frequent to call IncCount</param>
private void StartTimers( int milli )
{
Reset( );
_oneSecondTimer = new System.Timers.Timer( 1000 );
_tpsTimer = new System.Timers.Timer( milli );
_oneSecondTimer.Elapsed += DisplayData;
_tpsTimer.Elapsed += IncTPSCount;
_oneSecondTimer.Enabled = true;
_tpsTimer.Enabled = true;
}
}
}
Here is the code for the Windows Form app
using System;
using System.Windows.Forms;
using System.Threading;
/* ==============================================================================================
* Shows how to use two the System.Timers.Timer class instances to create a to display how many
* times a timer will trigger in one second.
*
* _tpsTimer triggers on a user specified value in the GUI. It will update _tpsCount which
* holds the number of times _tpsTimer was triggered.
*
* _oneSecondTimer will trigger every 1 second and will display the _tpsTimer value in the
* list box showing how many times _tpsTimer was triggered in 1 second.
*
* These methods can be used to try and control how fast something happens within 1 second. This
* is not SCIENTIFICALLY accurate, but it might be good enough to throttle down something like
* Frames Per Second to prevent flooding the network with too much streaming media.
*
* Because the timers run in a separate thread, the DisplayData function must use multithreading
* techniques to allow cross threaded data to be used in the GUI.
============================================================================================= */
namespace FPSTimer
{
public partial class FormSystemTimers : Form
{
// Ticks on 1 second intervals, used to trigger list box updates
private System.Timers.Timer _oneSecondTimer;
// Ticks on user specified interval, used to update _tpsCount variable
private System.Timers.Timer _tpsTimer;
// Represends how many times in 1 second _tpsTimer is fired off.
private int _tpsCount;
// Since timers run in differnt treads than GUI thread, need a delegate to
// update the GUI
public delegate void DisplayTPS( object source, System.Timers.ElapsedEventArgs e );
public FormSystemTimers( )
{
InitializeComponent( );
// Set initial state
Reset( );
}
/// <summary>
/// _oneSecondTimer tick event.
/// Updates the list box with the TPS count information. Function can be called from either
/// the GUI thread or one one of timer threads.
/// </summary>
/// <param name="state">Not using this state</param>
private void DisplayData( Object source, System.Timers.ElapsedEventArgs e )
{
if( this.lb1.InvokeRequired )
{
// Create the delegate and specify which function to call.
DisplayTPS d = new DisplayTPS( DisplayData );
this.Invoke( d, new object[ ] { source, e } );
}
else
lb1.Items.Add( "TPS COUNT : " + _tpsCount );
_tpsCount = 0;
}
/// <summary>
/// _tpsTimer tick event handler. Increments the TPS counter indicator.
/// </summary>
/// <param name="state"></param>
private void IncTPSCount( Object source, System.Timers.ElapsedEventArgs e )
{
_tpsCount++;
Console.WriteLine( _tpsCount );
}
/// <summary>
/// Resets all the controls and what not.
/// </summary>
private void Reset( )
{
if( _oneSecondTimer != null )
_oneSecondTimer.Dispose( );
if( _tpsTimer != null )
_tpsTimer.Dispose( );
_oneSecondTimer = null;
_tpsTimer = null;
lb1.Items.Clear( );
_tpsCount = 0;
if( tbMilli.Text == "" )
tbMilli.Text = "30";
}
/// <summary>
/// Resets controls, timers and restarts timers.
/// </summary>
/// <param name="milli">Specifies in milliseconds how frequent to call IncCount</param>
private void StartTimers( int milli )
{
Reset( );
_oneSecondTimer = new System.Timers.Timer( 1000 );
_tpsTimer = new System.Timers.Timer( milli );
_oneSecondTimer.Elapsed += DisplayData;
_tpsTimer.Elapsed += IncTPSCount;
_oneSecondTimer.Enabled = true;
_tpsTimer.Enabled = true;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click( object sender, EventArgs e )
{
if( tbMilli.Text == "" )
return;
int milli = Int32.Parse( tbMilli.Text );
if( milli > 0 && milli < 1001 )
StartTimers( milli );
}
/// <summary>
/// Calling this to kill the timers. If you don't do this, they continue to run after the
/// form starts to shut down which causes an exception. This is because the timer will still
/// try to call their tick handlers (updating the list), but the form controls have been killed,
/// so an exception happens. So, kill everyting BEFORE allowing the form to close.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_FormClosing( object sender, FormClosingEventArgs e )
{
Reset( );
}
}
}
Any feedback is greatly appreciated!
Thanks
Rick
Rick
Continue reading...
I wanted to create a timer that could app where I could monitor how many times a timer will tick per second. This all came about because I wanted to be able to throttle down how many times I was sending things over a network stream and I wanted to find the sweet spot in milliseconds and using a timer. Think FPS.
To do this I used two System.Timers.Timer objects.
_tpsTimer (ticks per second)
- Ticks on a user input interval so I can test to see how often I’d want to trigger based on FPS.
- Simply increments a counter variable “_tpsCount” tracking how many times its delegate was fired off
_oneSecondTimer
- Hard coded to 1000 milliseconds, 1 second.
- Displays the “_tpsCount” variable showing me how many times the _tpsTimer fired its event in one second.
I wrote a couple versions of the app. The logic behind these two apps are identical except for the fact that one is a winform one is a console. The two versions I’m most interested in posting about are
- SystemTimers – A Windows form app using System.Timers.Timer
- SystemTimersConsole – A console app using System.Timers.Timer
I was surprised at how much of a difference there was in ticks per second between a console app and windows form app. Is there REALLY that much overhead in a windows form app? Secondly, am I way off base in using timers for this purpose? Ultimately wanting to create a FPS throttle... How many images I send over a network per second.
The following image shows various tests at different millisecond intervals. The columns are :
- Milli Sec column : Millisecond interval.
- Console : At the given milli sec interval, how many times the timer was triggered for the Console application
- Win Form : At the given milli sec interval, how many times the timer was triggered for the Win Form application
Here is the code for the console app.
using System;
namespace SystemTimersConsole
{
class Program
{
// Ticks on 1 second intervals, Used to write _tpsCount every second
private System.Timers.Timer _oneSecondTimer;
// Ticks on user specified interval, used to update _tpsCount variable
private System.Timers.Timer _tpsTimer;
// Represends how many times in 1 second _tpsTimer is fired off.
private int _tpsCount;
// Since timers run in differnt treads than GUI thread, need a delegate to
// update the GUI
public delegate void DisplayTPS( object source, System.Timers.ElapsedEventArgs e );
static void Main( string[ ] args )
{
Program p = new Program();
p.Reset( );
// Param specifies millisecond frequency for _tpsTimer
p.StartTimers( 19 );
ConsoleKeyInfo i = Console.ReadKey( );
}
/// <summary>
/// _oneSecondTimer tick event.
/// Updates the list box with the TPS count information. Function can be called from either
/// the GUI thread or one one of timer threads.
/// </summary>
/// <param name="state">Not using this state</param>
private void DisplayData( Object source, System.Timers.ElapsedEventArgs e )
{
Console.WriteLine( "TPS COUNT : " + _tpsCount );
_tpsCount = 0;
}
/// <summary>
/// _tpsTimer tick event handler. Increments the TPS counter indicator.
/// </summary>
/// <param name="state"></param>
private void IncTPSCount( Object source, System.Timers.ElapsedEventArgs e )
{
_tpsCount++;
}
/// <summary>
/// Resets all the controls and what not.
/// </summary>
private void Reset( )
{
if( _oneSecondTimer != null )
_oneSecondTimer.Dispose( );
if( _tpsTimer != null )
_tpsTimer.Dispose( );
_oneSecondTimer = null;
_tpsTimer = null;
_tpsCount = 0;
}
/// <summary>
/// Resets controls, timers and restarts timers.
/// </summary>
/// <param name="milli">Specifies in milliseconds how frequent to call IncCount</param>
private void StartTimers( int milli )
{
Reset( );
_oneSecondTimer = new System.Timers.Timer( 1000 );
_tpsTimer = new System.Timers.Timer( milli );
_oneSecondTimer.Elapsed += DisplayData;
_tpsTimer.Elapsed += IncTPSCount;
_oneSecondTimer.Enabled = true;
_tpsTimer.Enabled = true;
}
}
}
Here is the code for the Windows Form app
using System;
using System.Windows.Forms;
using System.Threading;
/* ==============================================================================================
* Shows how to use two the System.Timers.Timer class instances to create a to display how many
* times a timer will trigger in one second.
*
* _tpsTimer triggers on a user specified value in the GUI. It will update _tpsCount which
* holds the number of times _tpsTimer was triggered.
*
* _oneSecondTimer will trigger every 1 second and will display the _tpsTimer value in the
* list box showing how many times _tpsTimer was triggered in 1 second.
*
* These methods can be used to try and control how fast something happens within 1 second. This
* is not SCIENTIFICALLY accurate, but it might be good enough to throttle down something like
* Frames Per Second to prevent flooding the network with too much streaming media.
*
* Because the timers run in a separate thread, the DisplayData function must use multithreading
* techniques to allow cross threaded data to be used in the GUI.
============================================================================================= */
namespace FPSTimer
{
public partial class FormSystemTimers : Form
{
// Ticks on 1 second intervals, used to trigger list box updates
private System.Timers.Timer _oneSecondTimer;
// Ticks on user specified interval, used to update _tpsCount variable
private System.Timers.Timer _tpsTimer;
// Represends how many times in 1 second _tpsTimer is fired off.
private int _tpsCount;
// Since timers run in differnt treads than GUI thread, need a delegate to
// update the GUI
public delegate void DisplayTPS( object source, System.Timers.ElapsedEventArgs e );
public FormSystemTimers( )
{
InitializeComponent( );
// Set initial state
Reset( );
}
/// <summary>
/// _oneSecondTimer tick event.
/// Updates the list box with the TPS count information. Function can be called from either
/// the GUI thread or one one of timer threads.
/// </summary>
/// <param name="state">Not using this state</param>
private void DisplayData( Object source, System.Timers.ElapsedEventArgs e )
{
if( this.lb1.InvokeRequired )
{
// Create the delegate and specify which function to call.
DisplayTPS d = new DisplayTPS( DisplayData );
this.Invoke( d, new object[ ] { source, e } );
}
else
lb1.Items.Add( "TPS COUNT : " + _tpsCount );
_tpsCount = 0;
}
/// <summary>
/// _tpsTimer tick event handler. Increments the TPS counter indicator.
/// </summary>
/// <param name="state"></param>
private void IncTPSCount( Object source, System.Timers.ElapsedEventArgs e )
{
_tpsCount++;
Console.WriteLine( _tpsCount );
}
/// <summary>
/// Resets all the controls and what not.
/// </summary>
private void Reset( )
{
if( _oneSecondTimer != null )
_oneSecondTimer.Dispose( );
if( _tpsTimer != null )
_tpsTimer.Dispose( );
_oneSecondTimer = null;
_tpsTimer = null;
lb1.Items.Clear( );
_tpsCount = 0;
if( tbMilli.Text == "" )
tbMilli.Text = "30";
}
/// <summary>
/// Resets controls, timers and restarts timers.
/// </summary>
/// <param name="milli">Specifies in milliseconds how frequent to call IncCount</param>
private void StartTimers( int milli )
{
Reset( );
_oneSecondTimer = new System.Timers.Timer( 1000 );
_tpsTimer = new System.Timers.Timer( milli );
_oneSecondTimer.Elapsed += DisplayData;
_tpsTimer.Elapsed += IncTPSCount;
_oneSecondTimer.Enabled = true;
_tpsTimer.Enabled = true;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click( object sender, EventArgs e )
{
if( tbMilli.Text == "" )
return;
int milli = Int32.Parse( tbMilli.Text );
if( milli > 0 && milli < 1001 )
StartTimers( milli );
}
/// <summary>
/// Calling this to kill the timers. If you don't do this, they continue to run after the
/// form starts to shut down which causes an exception. This is because the timer will still
/// try to call their tick handlers (updating the list), but the form controls have been killed,
/// so an exception happens. So, kill everyting BEFORE allowing the form to close.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_FormClosing( object sender, FormClosingEventArgs e )
{
Reset( );
}
}
}
Any feedback is greatly appreciated!
Thanks
Rick
Rick
Continue reading...