VB.NET: Main o Modello di Applicazione

In Visual Studio 2003 se erano necessarie inizializzazioni prima di avviare la Main Form dell’applicazione si ricorreva alla stesura di una Sub/Funcion Main (a riguardo si veda Routine Main in Visual Basic).

A partire da Visual Studio 2005 VB.NET si è arricchito del Modello di Applicazione che comprende eventi per la gestione dell’avvi e della chiusura dell’applicazione e eventi per l’intercettazione di eccezioni non gestite. Inoltre fornisce il supporto per lo sviluppo di applicazioni a singola istanza ed è estensibile tramite la personalizzazione dei metodi overridable contenuti nel modello.

Per ulteriori informazioni si veda Cenni preliminari sul modello di applicazione Visual Basic.

Dal seguente Estensione del modello di applicazione Visual Basic è possibile vedere lo schema della sequenza di chiamata del modello di applicazione che viene avviata quando la Sub Main esegue la chiamata al metodo Run.

Modello di applicazioni Visual Basic -- Esecuzione

Come si può notare i punti in cui intervenire sono vari e quindi i casi in cui è necessario scrivere una sub Main non sono poi molti, infatti buona parte delle inizializzazioni può essere inserita nell’evento Startup che può anche arrestare l’avvio se la proprietà Cancel dell’argomento di evento viene impostata a True.

Il Modello di Applicazione di VB.NET (in C# non è disponibile) è disponibile solo per progetti Windows Forms Application, mentre in progetti Console Application si dovrà ricorrere alla stesura di una Sub Main.

Un motivo per cui può comunque essere necessario scrivere una Sub Main è ad esempio invocare il metodo SetCompatibleTextRenderingDefault. A partire da .NET 2.0 (Visual Studio 2005) nelle applicazioni Windows Forms in VB.NET il rendering del testo viene eseguito per default tramite GDI e non più tramite GDI+ come accadeva col framework .NET 1.0 e 1.1 (Visual Studio 2002 e Visual Studio 2003). Questo perchè anche se GDI+ espone API estremamente semplici da utilizzare, GDI offre alcuni vantaggi:

  • il look dell’applicazione è più consistente con le dialogs del sistema operativo;
  • ha un migliore supporto per la localizzazione e per il rendering dei caratteri Unicode ;
  • Il rendering è molto più veloce e può sfruttare anche l’accelerazione hardware.

Un motivo per cui può essere necessario utilizzare una Sub Main può essere quello di tornare la modalità compatibile con .NET 1.0 o .NET 1.1 ovvero invocare la SetCompatibleTextRenderingDefault col parametro True prima della creazione chiamato prima della creazione del primo oggetto IWin32Window o per meglio dire prima che sia stato creato un handle andando a vedere l’implementazione del metodo tramite Reflector:

Public Shared Sub SetCompatibleTextRenderingDefault(ByVal defaultValue As Boolean)
    If NativeWindow.AnyHandleCreated Then
        Throw New InvalidOperationException(SR.GetString("Win32WindowAlreadyCreated"))
    End If
    Control.UseCompatibleTextRenderingDefault = defaultValue
End Sub

Quindi non sarà possibile invocare SetCompatibleTextRenderingDefault nè in un ovveride del metodo OnInit nè tanto meno nell’evento OnStartup.

Nelle applicazioni C# invece occorre invocare la SetCompatibleTextRenderingDefault con il parametro false, ma Visual Studio 2008 per le applicazioni Windows Forms crea già automaticamente un Program.vb con i seguenti contenuti:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Windows.Forms;

namespace WindowsFormsApplication1

{

    static class Program

    {

        /// <summary>

        /// The main entry point for the application.

        /// </summary>

        [STAThread]

        static void Main()

        {

            Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new Form1());

        }

    }

}

Se si opta per l’implementazioni di una Sub Main occorre ricordarsi di decorarla con l’attributo STAThread in quanto lo STAThreadAttribute indica che il modello di threading COM per l’applicazione è apartment a thread singolo. Tale attributo deve essere presente sul punto di ingresso di qualsiasi applicazione che utilizza Windows Form, in caso contrario è possibile che il componente Windows non funzioni correttamente. Infatti se l’attributo non è presente, l’applicazione utilizza il modello apartment multithreading che non è supportato da Windows Form.