• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
maya18222

WPF - Trying to get a timer with an interval of less than ~16ms

5 posts in this topic

I'm trying to devise a way of a getting some kind of timer to signal an event in my WPF application with an interval of around 5ms. My attempts with using a DispatchTimer or a Timer and having the interval set to 1ms, lead to their "tick" events being triggered at only around 60 times a second, which isnt fast enough.

Is there any way I can achieve something faster? either through some event mechanism or by any other means?

I would like something similar to that of a win32 application, as shown below.
int Application::run(){   while(msg.message != WM_QUIT)   {	    if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) // If there are Window messages then process them.	    {			 TranslateMessage( &msg );			 DispatchMessage( &msg );	    }	    else // Otherwise, do my work	    {    		    	    }   return (int)msg.wParam;}
I assume this is how WPF is doing it in the background with its Application.Run(Window()) method. Is there anyway of getting some kind of callback on that "else" branch? Edited by maya18222
0

Share this post


Link to post
Share on other sites

Ohai!

 

First, some background: the DispatchTimer does not create another thread to run its stuff on, it is periodically checked from the WPF UI thread. This is why you can access UI elements directly and not get an exception. Now, the UI thread itself, (and here is where I start assuming stuff without any real base) is running once per rendered frame (running multiple time would be wasteful). Now, the rendering frame, my guess, is vsync ... umm... synchronized. So, no matter how small you'll set the interval of a DispatcherTimer, it won't be checked faster than your refresh rate (which, coincidentally, is almost always 60 hertz).

 

Now, what I would do: I would start a BackgroundWorker (which creates a different thread) and run an infinite loop in which I do my work and then sleep a bit (5 ms  minus the_time_it_got_to_do_my_work_this_frame ). Now all would be nice and well if I wanted to check stuff that is "external" to WPF (like stream some stuff from the HDD, check for a network message, etc).

 

And from here, trouble: if you would want to access and, heaven forbid, modify UI elements from the secondary thread (our BackgroundWorker), you would have to use Dispatcher.Invoke or Dispatcher.BeginInvoke, and this is where things get messy: Dispatcher.Invoke or Dispatcher.BeginInvoke (msdn it to see the difference or PM me) do their work on the , yes, you guessed it, the Dispatcher thread (in our case the WPF UI one). And, as with everything dispatcher-driven, it is the WPF UI that checks the Invoke or BeginInvoke work queues, yep, you've guessed it, ONCE PER RENDERED FRAME.

 

So, if you go the BackgroundWorker route BUT you NEED to access or modify at least one UI element EVERY loop, then your update rate will slow down to 60 times per second (if you use beginInvoke this won't happen, but the UI changes will be the same - 60 hertz - in both cases). 

 

My recommendation is (and this is a general WPF recommendation): split the UI logic from the application logic and UPDATE THE UI ONLY WHEN YOU REALLY NEED IT. So you should do your update cycle once every 5 ms, if you have to, but don't touch the UI unless when and if you really need to (and never once per update cycle).

 

And the real answer: i am unaware of any way to SPEED UP the WPF update cycle (but I guess it's definitely not recommended either way).

 

Cheers!

0

Share this post


Link to post
Share on other sites

I'm not sure, but I think WPF timers use native win32 timers, which, if I remember correctly, are limited to 10-15ms accuracy. "Multiple timer messages get merged into one because they are implemented as a flag in GetMessage()", whatever that means exactly. Alternatives, which I admit I haven't needed to investigate yet, include multimedia timers and waitable timer objects. I remember reading it's actually impossible to get VERY ACCURATE timer event notifications from the OS in Windows in user-mode code. Obviously I'm not certain about anything I've just said wacko.png

0

Share this post


Link to post
Share on other sites

As Amr0 and others have said above, DispatchTimer and System.Threading.Timer et. al. use regular Win32 timers and/or GetTickCount() under the hood and therefore have resolution in the 10-15 millisecond range at best. 

 

If you want better resolution than this you need to use the C# eqivalent of the Win32 call QueryPerformanceCounter(): this is what the C# class System.Diagnostics.Stopwatch() is. However, StopWatch is intended to be used to measure durations -- basically for profiling purposes, which is why it is in the Diagnostics namespace -- not to drive the flow of control of a program with events and/or callbacks like the other kinds of timer. 

0

Share this post


Link to post
Share on other sites

Thank you for the replies. Im actually trying to come up with a way of updating winForms controls in a wpf application at a rate of several hundred FPS.

My first approach was just

DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(1);
dt.Tick += new EventHandler(OnProcessViewports);
dt.Start();

which as mentioned, gives me arounf 60 FPS.

Ive now tried

Loaded += (s, a) =>
		    {
			    BackgroundWorker bw = new BackgroundWorker();
			    bw.DoWork += (ss, aa) =>
			    {
				    while (true)
				    {
					    Thread.Sleep(16);
					    Dispatcher.Invoke(new EventHandler(OnProcessViewports), new object[] { null, null });
				    }
			    };
			    bw.RunWorkerAsync();
		    };

This works, and gives me several hundred FPS (with a low sleep time), which is what I wanted. But, something odd is happeneing with the CPU usage. If I set the sleep time to about 16ms, then I get around ~55FPS, but, .. the CPU usage goes to about 20-30%.

using the dispatch timer approach as coded above, I get 60 FPS, and around 2-3% CPU usage. Any ideas why this would be the case? Both versions run at around 60FPS, yet the 2nd approach uses a lot more CPU usage.

Edited by maya18222
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0