7
votes

Comment accélérer le chargement de l'écran des éclaboussures

J'épanouie le démarrage d'une application WinForms. Un problème que j'ai identifié est le chargement de la forme de l'écran des éclaboussures. Il faut environ une demi-seconde à une seconde.

Je sais que Multi-threading est un non-non sur des pièces d'interface utilisateur, cependant, voyant comment l'écran Splash est un élément de l'application assez autonome, est-il possible d'atténuer d'une manière ou d'une autre que ses performances frappées en le jetant un un peu d'autre fil (Peut-être dans la manière dont chrome le fait), de sorte que les éléments importants de l'application puisse y aller.


0 commentaires

6 Réponses :


1
votes

oui.

Vous devez créer un nouveau fil de STA qui affiche l'écran Splash à l'aide de Application.run code>, puis appelez Fermer code> à l'aide de Invoke Code> Une fois que la forme principale est prête (sur le fil principal). p>

EDIT STRY>: Par exemple: P>

static SplashForm splash;

Thread splashThread = new Thread(delegate() {
    splash = new SplashForm();
    Application.Run(splash);        //Blocking call on separate thread    
});
splashThread.SetApartmentState(ApartmentState.STA)
splashThread.Start();

LoadApp();

//In MainForm_Shown:
splash.BeginInvoke(new Action(splash.Close));


4 commentaires

C'est une approche intéressante. Pouvez-vous développer comment faire un fil de STA.


Le frai d'un fil est contre-productif. L'objectif est de minimiser le temps nécessaire à l'écran des éclaboussures, alors pourquoi la ralentissez-la en partageant ses cycles avec le reste du processus de chargement des applications? Il est préférable de consacrer tout pour montrer l'éclaboussure, puis chargez le reste de l'application.


@CHARDLES: Si vous affichez l'éclaboussure sur le fil principal, il n'obtiendra aucun message et cessera de répondre.


vrai, mais pas généralement un problème dans mon expérience (voir commentez ma réponse). En fin de compte, c'est une décision de conception, et je pense que les deux approches ont leur place. (Au fait, l'écran des éclaboussures sera obtenir des messages une fois que l'application est chargée, bien que je réalise que cela soit probablement discutable.)



1
votes

La multithreading in Winforms est correcte tant que toute l'interface utilisateur reste sur un fil.

C'est à quel point les écrans SPLASH sont généralement effectués. Le travail important est effectué sur un fil d'arrière-plan, tandis que la fenêtre SPLASH SCREE est affichée sur le thread d'interface utilisateur pour que l'utilisateur sache que le reste du programme apparaisse bientôt.

Après que les trucs importants se produisent, soulevez un événement pour que le fil de l'interface utilisateur sache qu'il est temps de cacher l'écran de l'éclaboussure (rappelez-vous simplement de marshaler le gestionnaire d'événements, à l'aide d'invoke (), de retour sur le fil de l'interface utilisateur afin de Fermez l'écran Splash).


0 commentaires

4
votes

Il n'y a rien à gagné de reproduire un fil si votre objectif est d'obtenir l'écran des éclaboussures le plus rapidement possible.

Il y a plusieurs façons de faire des écrans éclaboussures, et plus sophistiqué est mentionné ici , mais c'est une méthode facile que j'ai utilisée avec succès complet: p>

Il suffit de vous assurer de charger et d'afficher le formulaire Splash premier fort>, puis continuez à charger votre application pendant que l'utilisateur est En regardant l'écran joli éclaboussure. Lorsque le formal principal est effectué en cours de chargement, il peut fermer l'éclaboussure juste avant de se montrer elle-même (un moyen simple de le faire est de passer le formulaire Splash sur le formulaire Mainforme dans son constructeur): P>

static class Program
{
    static SplashForm _splash;

    [STAThread]
    static void Main()
    {
        Application.SetCompatibleTextRenderingDefault(false);
        _splash = new SplashForm();
        _splash.Show();
        _splash.Refresh();
        Application.EnableVisualStyles();
        MainForm mainForm = new MainForm();
        mainForm.Load += new EventHandler(mainForm_Load);
        Application.Run(mainForm);
    }

    static void mainForm_Load(object sender, EventArgs e)
    {
        _splash.Dispose();
    }
}


4 commentaires

Si vous affichez la splash sur le fil principal, il ne sera pas en mesure de traiter les messages Windows et n'arrête pas de répondre.


Oui, et cela peut être un problème si l'application prend beaucoup de temps à charger et que le développeur souhaite que l'utilisateur puisse interagir avec l'écran des éclaboussures en attendant. Mais pour les applications qui se chargent d'une période raisonnablement courte, l'interaction avec l'écran des éclaboussures n'est normalement pas souhaitée.


Si elle se charge en peu de temps, il y a peu de point à l'aide d'un écran éclabousseur.


Mais les écrans éclaboussures sont ... Splashy. :)



9
votes

Le .NET Framework a déjà un très bon support pour les écrans Splash dans les applications Windows Forms. Vérifiez ce fil pour un échantillon de code. Il est en effet optimisé pour le temps de démarrage au chaud, il veille à ce que le filetage et l'écran des éclaboussures soient opérationnels et fonctionnent avant d'initialiser l'application principale.


0 commentaires

1
votes

La réponse est vraiment sur la perception. Il existe différentes méthodes, Ngen un assemblée, mettant des choses dans le GAC, mais ce que vous devriez comprendre est ce qui se passe vraiment.

C # nécessite du temps pour charger la machine virtuelle, charger des assemblages référencés et charger les ensembles en fonction de ce qui est sur cet écran de démarrage. Et puis il prend toujours un certain temps à partir d'un début "froid" pour lancer le premier écran.

Ceci est dû à la compilation JIT qui se passe lorsque vous accédez d'abord à un écran.

Une stratégie que j'utilise est une page splash légère traditionnelle qui charge rapidement de sorte que son visible, mais dans l'arrière-plan, j'apparaisse un fil et chargez une forme invisible. Ce formulaire a toutes les commandes que j'ai l'intention d'utiliser et que le compilateur JIT fait donc sa chose et son chargement des assemblages. Cela fournit l'illusion de la réactivité avec une légère main. Le temps qu'il prend à partir de lancement + page de splash visible + pause + cliquez sur la 1ère option, c'est plus grand que l'heure à laquelle il faut le fil pour exécuter, puis nettoyer et décharger le formulaire.

Sinon, les applications semblent être maladroites et ralentissent pour les utilisateurs quand il commence d'abord. Le démarrage chaud des écrans est beaucoup plus rapide car les assemblages et JIT ont terminé.


0 commentaires

1
votes

Nous le faisons en fournissant une petite application native C ++ qui sert d'écran de splash.

Il suit ensuite ce processus:

  1. L'utilisateur double clique sur l'icône de l'application.
  2. L'application C ++ commence, montrant un bitmap Splash comme ws_toplose le plus.
  3. L'application C ++ lance l'application C # principale.
  4. L'application C # commence, notifiant enfin l'application C ++ (via un fichier simple) pour quitter.
  5. L'application C ++ quitte.

    L'application C ++ a également un délai d'attente (au cas où l'application C # se bloque) et s'absenne automatiquement s'il n'est pas notifié pour cesser de fumer dans les 30 secondes.

    Cette approche a ses inconvénients dans le fait que vous ne pouvez pas broyer l'application à la barre des tâches. Si vous épinglez l'application C ++ (qui est l'application principale pour l'utilisateur final), vous obtenez une autre tâche dans la barre des tâches, car l'application C # est différente. Je pense que je pourrais résoudre ceci en fournissant des paramètres dans le Application Manifest de l'application C ++ et C # pour leur instruire d'être la "même" application en termes de barre de tâches.


0 commentaires