C# Timers, having issues

Started by
14 comments, last by keinmann 13 years, 6 months ago
In Windows.Forms programming, you can always use Form.Invoke(delegate) to execute something on the proper UI thread; which is a MUST with Winforms. You can't touch a control from any other thread. See the "MethodInvoker" class which can be very helpful in this scenario. Basically, the thread is asking the main UI thread to do { whatever(); } on the correct thread so you can access controls without violating the rules. You can also check "InvokeRequired" to know if this is necessary or if you can access controls as normal. To me: overkill. Just do it. There is a way to get around this single-threaded UI rule, but I won't even say how because it's a pretty dirty thing to do, imho. Do it right.

Still, stray away from that where you can. My timer above will work fine, even if there is a little delay in the message loop. I let it sit idle for HUGE periods of time before calling Step() again and it still kept the correct time. So it won't suffer that, and the resolution/frequency is as good as the underlying hardware can provide. You can't even hurt it from calling Step too fast; it still stays on track. I tested nearly every case I could think of, and she works fine! :)

@voguemaster: Thanks, and your additional info will probably help many!
Advertisement
Quote:Original post by voguemaster
3. You also allocated a thread for drawing. It operates on a graphics object but what thread was the control from which that graphics is derived from ? (unless you're doing something else entirely). Usually you can't do stuff like that if you allocated a Control in thread #1 and you try to change its state from thread #2.

I don't know how it even worked, unless there's something I'm missing.


I defined a Graphics member in my Form1 class and initialized it in Form1_Load, the bitmap that the graphics object draws to is set to the form's background image.

hi,

Keinmann, since you touched on the Invoke delegate issue, I want to also add that it can be quite expensive in certain circumstances. Sometimes passing objects via those delegates will cause them to be serialized and de-serialized so they can be passed to the UI thread, an expensive operation to be sure.

Anyway, I took a look at the example code you posted, quite nice indeed :)
-----------------------------He moves in space with minimum waste and maximum joyGalactic Conflict demo reel -http://www.youtube.com/watch?v=hh8z5jdpfXY
@ voguemaster:

Well, you taught me something new. Never considered the performance consequences of Form.Invoke(delegate) before. Reason being that I only use it in non-game Winform applications. As a general rule of thumb, I try to avoid having a thread that needs to tamper with Control objects; sometimes tough though when you need to update a status bar in a long operation. I don't want to hijack the OP's thread, but does the dilemma you describe apply with this sort of usage?

Action action = new Action(() =>                {                    DoSomethingOnUIThread();                    UpdateData();                    Whatever();                });this.Invoke(action);


...assuming "this" is a Winform? That's about as complicated as I ever let things get with another thread "talking" to controls/UI thread; just for the sake of design and cleanliness.

And thanks for your positive feedback on my code! That's straight production code from my (incomplete) SlimDX/D3D11 engine. That's how much of it looks: clean, simple, fast and loosely coupled with other implementations (or totally decoupled in this case). I like to build complex systems from simple, maintainable parts. I hope that little class can help folks as much as you have helped by sharing some knowledge with us!

Interlocked.Increment(ref your_rating); :)
Actually, yes. Thread marshalling will be used when you invoke a delegate on a control like you described. This happens also when switching between AppDomains for example.

What this really mean is that arguments to the delegate function will have to be serialized and de-serialized. There is no way around it in this case.

If the code is not performance critical in any way or such an invocation doesn't occur often, don't think of it. I just wanted to alert it to anyone that may be interested :-)
-----------------------------He moves in space with minimum waste and maximum joyGalactic Conflict demo reel -http://www.youtube.com/watch?v=hh8z5jdpfXY
Well thanks again! That's nice to know in any case. :)

I have a few more questions about it, just for the sake of learning more. But I'll take it up with you via pm.

@ Chris:

I hope you got my pm with the original GameClock.cs file, and that you have resolved your issues!

This topic is closed to new replies.

Advertisement