Wednesday, 30 December 2009

Writing a correct Main Loop for your application

Have you ever wondered how can Windows run more than one application at a time, even in a single-processor machine? The answer is easy. It doesn’t. The point is that it switches from one application to another so fast that you don´t notice the change, and it seems both applications are running in parallel.
To allow this, running Windows applications should not always be running.
It´d be a waste of resources to massively use the processor just to find out that nothing had to be done, don’t you think?. That´d be kind of a psychotic behavior. Windows has it´s protocols and procedures to avoid this, letting applications or threads enter idle states, even for a few milliseconds, and giving then priority to other, non-idling processes.
So, what would happen if your application never enters idle mode? It would bring down the multi-tasking capability of Windows, slowing down every other application than yours. That´s why I say that running applications should not always be running.
Under this point of view, applications can be divided into three groups:
  1. Psychotic applications that should be updated always, i.e. intense computing applications (not so frequent, nowadays)
  2. Applications that should be updated only as a response to some user interaction (most Windows Forms applications)
  3. Applications that sometimes need to be “always updated”, and sometimes not (like a video-game)
As you know, when an application is run, the Main method is invoked, and the O.S gives the application access to the processor and some memory. Apart from thread priority policies, application´s behavior will be one or another depending on what we do in this Main() method:

Case # 1. Compute, compute, compute

The Main method structure is simple: update as fast as you can, and consume as much processor as possible. The Main() method in pseudo-code:
            while (Application is Alive)
            {
                Compute()
            }
This is the typical behavior of old applications in non multi-tasking environments. They consume as much processing power as is available.

Case # 2. Don´t disturb unless absolutely necessary

What should be done here is easy: if events are pending, process them (DoEvents). If not, just relax and sleep, yielding processor to other threads or applications. The exact implementation of such a procedure can be more complex, as we should decide when to enter sleep modes and when not. Luckily, .Net does that for us. The C# implementation you should use is:
            System.Windows.Forms.Application.Run(mForm);
The Run() method takes care of all the things above mentioned (yielding and many other things), and it does it using the standard .Net procedures and protocols.

Case # 3: The mixed approach

Other situations need a mixed solution. For example, a Windows Forms application that sometimes needs to enter a “running” state, where everything has to be updated, like a Windows Forms-based video-game, or a 3D editor where you want to run an animation. Here, updates will be applied when the application is in Running state, but not when it´s not, saving this way CPU (and batteries, if running in a laptop).
So, we want to combine the efficiency of Case # 2, with the possibility of switching to Case # 1 when needed. The correct implementation for this, in C#, is:
       ...
            System.Windows.Forms.Application.Idle += new EventHandler(Application_Idle);
            System.Windows.Forms.Application.Run(mForm);
        }
        static void Application_Idle(object sender, EventArgs e)
        {
            if(Application.RunningState)
            {
                 while(ApplicationStillIdle)
                      Compute();
            }
        }
The Application_Idle event will be fired each time the application is about to enter in Idle state (where all the pending messages for the windows has been processed).
This way, interaction between our application and others (running at the same time) will be correct: when we decide it (activate running state), we will have all the computing power for ourselves, but when it´s not needed (RunningState is off), we will yield it.

How to check if application is still Idle

The Application_Idle event is fired only once, when the application is about to enter idle state. Here, we will have to update computations while it is still Idle, giving priority to Windows Messages if there are some. How to check if the application is still Idle? Easy, we can use a property like the following:
        /// <summary>Checks to see if the application is still idle</summary>
        private bool AppStillIdle
        {
            get
            {
                NativeMethods.Message msg;
                return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
            }
        }

An extra option to make things even better

We have seen how to activate/deactivate the psychotic (processor consuming) behavior of an application, basing on a state variable, but sometimes it is interesting to also deactivate it when our application does not have the focus (it is not the active application in the O.S.).
Windows controls and forms have a “Focused” property, but that doesn’t help much in this case, as we want to check if the entire application has focus, not an specific form (the main form of the application will loose focus often, when we open a child window, for instance).
Then, how to check if our application is the active application in Windows? Unfortunately, it seems that there is no C# managed code to check that, but we can easily use DLLImport to invoke the “GetForegroundWindow” method, comparing its result to our main form handle:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
 
public bool MyAppFocused
{
    get { return GetForegroundWindow() == this.Handle; }
}
This way, we can put an additional condition to the Compute method, deactivating it also when the application is not focused:
static void Application_Idle(object sender, EventArgs e)
{
   if(Application.RunningState && MyAppFocused)
   {
       while(ApplicationStillIdle)
            Compute();
   }
     }

What should not be done

Some people tend to write the following code when need the mixed solution mentioned:
while (mForm.Created)
{
      System.Windows.Forms.Application.DoEvents();
 
      if(Application.RunningState)
             Compute();
}

Though it works, this approach is not correct, as it doesn’t yield processor to other threads (your application won´t enter idle mode). Use the above Idle event approach instead.

Conclusion

Quality software use the processor when really need it. Adding a few extra lines of code, you software will better share resources with other applications, and will improve laptop or handheld device´s battery life.
Take Care!

Saturday, 19 December 2009

AutoBild estudia los efectos del cansancio y del alcohol al volante con simuladores Simax

En el número de esta semana de AutoBild (nº 214, del 18 al 24 de Diciembre de 2009), se publica la primera parte de un estudio realizado en colaboración con Toyota España y Simax, en el que se analizan los efectos del cansancio y del consumo de alcohol en la conducción.

PortadaAutobild¿Y qué mejor manera para hacerlo que realmente analizar la conducción de voluntarios en condiciones de fatiga reales, y después de haber bebido? Y no nos referimos a 10 minutos de test, sino a 2 horas seguidas conduciendo en un entorno monótono como una autovía, para incrementar todavía más el cansancio y el peligro. Además, y para obtener la mayor cantidad de información posible, hemos comparado sus resultados con los de otros voluntarios, descansados y sobrios.

Por razones obvias, este estudio no puede hacerse en la vía pública, y un circuito cerrado no sirve, ya que tendrían que estar 2 horas dando vueltas a un circuito, sin tráfico, y que nada tiene que ver con una carretera real.

La solución diseñada por AutoBild ha sido utilizar simuladores Simax, cedidos por Toyota España. Nos propusieron la idea y desde el principio nos encantó, así que nos pusimos manos a la obra.

Además de permitir a los conductores circular por una vía real (autopista), e interactuar con tráfico, desde Simax diseñamos un ejercicio en el que, a lo largo de 2 horas, los conductores irían enfrentándose a incidencias de tráfico de dificultad creciente. Desde una simple balsa de agua en la calzada, hasta un desprendimiento de rocas.

Los simuladores Simax monitorizan en todo momento todas las reacciones de los conductores y los vehículos, lo que nos ha permitido extraer conclusiones de lo más interesantes. Tenéis vuestro ejemplar de AutoBild en el quiosco.

¡No os lo perdáis!

La semana que viene se publica la segunda parte del estudio, y las conclusiones finales.

Monday, 7 December 2009

My ListView won´t show groups! Why?

This is a well documented issue, but just in case it helps someone.

If your ListView doesn't show groups, ensure the following (starting with the most obvious, and ending with the probable cause):

  1. Ensure your ListView has, at least, one column
  2. Ensure you have created Groups correctly
  3. Properly assign a group to each Item, through their “Group” property
  4. Set listView.ShowGroups property = True
  5. Ensure you have called System.Windows.Forms.Application.EnableVisualStyles() method at the beginning of your application

ListView groups rely on VisualStyles of the application, what is only available on Windows XP systems and above. So, groups won´t work on anything below Windows XP.

Here, you can find some explanations, like the following:

“ListView groups are available only on Windows XP and Windows Server 2003 when your application calls the Application.EnableVisualStyles method. On earlier operating systems, any code relating to groups has no effect and the groups will not appear. As a result, any code that depends on the grouping feature might not work correctly.”

Cheers!