tags:

views:

278

answers:

3

I have a problem with interface lag in C#.

Since I'm still learning please be patient whilst I explain.

I have narrowed the problem to my timer object.

Basically my program queries a device through TCP/IP socket and outputs it to a textbox on screen.

Now I'm polling the device for data every second which requires some logic to be buried within timer object and the following is what happens between ticks:

1) increment a value.
2) construct the 2 strings that represents the command to be sent to the box (encapsulated in a function
3) Encode the command
4) send command
5) clear the byte array
6) receive reply.

could this be too much processing being done in the event handler? Every time I try to move the window during the polling session i.e. when the timer is running I get a bad input lag. very bad input lag.

+1  A: 

It seems like there are a few things going on. First, you may be doing too much in your timer tick handler. How are you constructing the string and encoding the command? Can any of this be done once outside the tick handler or simplified in any way (using String.Format calls, for instance)? There are actually three different timers available in .NET, with different resolutions. Which timer are you using?

The biggest issue is the fact that your interval is 1 second. No matter what, that is a lot of processing overhead. Keep in mind that, for the most part, every time the interval is hit and the tick handler is invoked you are causing a context switch between threads. There is a bit of overhead involved in this (nothing which you can do anything about) and the more often you context switch the slower your performance appears.

Scott Dorman
+10  A: 

The timer you are using is executing on the windows message thread. Therefore, while the polling is running the windows message queue is blocked. This isn't a problem with doing too much processing, most of the time the thread will be waiting for the TCP/IP response.

To fix this, you just have to do the do the work on a background thread and then update the UI on the UI thread.

There are a heap of different timers in the .NET framework that work in different ways, the one you are using works processed the timer event on the same thread, others work on background threads. Check this article out about the different timers.

You cound also just use your current timer to invoke a BackgroundWorker component to do the work on the background thread. The main benefit of this is the the BackgroundWorker will do the work on a background thread, but will raise the work complete event on the UI thread so that it is simple to update the UI without having to worry about which thread you are on.

Pete Davis
I have tried everywhich way now (BackgroundWorker, separate thread) but no matter what I do my UI is still being held Hostage for the duration of the polling period, in most instances I'm not even able to interupt the polling process(unless I sleep the working thread) I am now at a loss of how to implement this logic.
Dark Star1
+2  A: 

I think this is because you're trying to do work in your UI thread. Have your timer run in a background work thread.

elan