Question

Je montre un écran d'accueil sur un fil de fond pendant que mes charges de programme. Une fois qu'il charge j'ABORTING le fil car il est le seul but était de montrer une forme de démarrage Now Loading.

Mon problème est que quand un fil il avorter jette un ThreadAbortException que l'utilisateur peut simplement cliquer sur Continuer sur.

Comment puis-je régler ce problème? Je tentais de le supprimer comme si ->

            try
        {
            Program.splashThread.Abort();
        }
        catch(Exception ex)
        {

        }

mais j'ai un sentiment qui va me faire engueuler ici et il ne fonctionne pas ainsi.

Merci!

Était-ce utile?

La solution

Vous n'avez pas besoin d'annuler le fil. Je vais exemplifie avec le code.

Dans la forme de l'écran d'accueil:

public void CloseSplash()
{
    Invoke((MethodInvoker)delegate
    {
        this.Close();
    });
}

Dans le fichier Program.cs:

private static Splash _splash = null;
public static void CloseSplash()
{
    if (_splash!= null)
    {
        _splash.CloseSplash();
    }
}

Maintenant, quand votre méthode principale commence, montrer les éclaboussures dans un thread:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
    _splash.ShowDialog();
}));

t.Start();

... et quand vous le voulez fermer, il suffit de fermer:

Program.CloseSplash();

Ensuite, vous n'avez pas à vous soucier de fil interrompre le; il sortira avec élégance.

Autres conseils

S'il vous plaît consulter le lien suivant obtenu faisant une recherche Google (premier résultat retourné):

http://msdn.microsoft.com/en-us/library /5b50fdsz.aspx

Portez une attention particulière à cette partie:

Lorsque cette méthode est invoquée sur un fil, le système lance une ThreadAbortException dans le fil pour l'interrompre. ThreadAbortException est une exception qui peut être pris par le code d'application, mais est à nouveau jeté à la fin du bloc catch à moins ResetAbort est appelé. ResetAbort annule la demande pour annuler, et empêche la ThreadAbortException de terminaison du fil. Enfin blocs non exécutés sont exécutés avant que le thread est interrompu.

Utilisation Threadabort ne recommened. Il est le mal. Pourquoi ne pas utiliser un autre mécanisme comme un (Auto / Manuel) ResetEvent? Démarrer le fil avec l'écran de démarrage, attendez l'événement. Si l'autre code est fait des choses chargement, définissez l'événement en permettant l'écran de démarrage se fermer la voie normale (agréable).

Quelques points. L'exception est la raison pour ThreadAbort le fil avorte. Il n'est pas un effet secondaire de vous appeler abort. Lorsque vous appelez abandonner sur un fil, le moteur d'exécution force une exception threadabort à se propager au fil. Cette exception peut être pris, car il permet à l'utilisateur d'effectuer un nettoyage avant que le thread avorte.

L'exception est relancée alors automatiquement pour assurer que le fil est interrompu. Si l'exception a été capturé et si elle n'a pas été relancée le fil ne serait jamais abandonner.

design vraiment intelligente fait.

Il est vraiment OK pour attraper cette exception. En fait, vous devriez. Mais attraper seulement exception spécifique et non l'exception générale. (Voir ci-dessous)

catch(ThreadAbortException ex)
{
   //This is an expected exception. The thread is being aborted
}

Modifier le type d'exception à ThreadAbortException et ajoutez un appel à ResetAbort ()

    try
    {
        Program.splashThread.Abort();
    }
    catch(ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }

En général, les discussions est considéré comme l'interruption pratique très mauvais et peut conduire à toutes sortes de mal à traquer les bugs. Avez-vous envisagé de trouver un moyen juste fermer la fenêtre de démarrage ou utiliser une sorte de vote pour arrêter le fil quand un drapeau a été mis en?

Pourquoi voudriez-vous faire? Il suffit de définir un drapeau que les sondages de fil, puis finalement quand le fil ramasse ça va se fermer.

Essayez ce code. Il fonctionne très bien pour moi.

void splash()
{
    try {
        SplashScreen.SplashForm frm = new SplashScreen.SplashForm();
        frm.AppName = "HR";

        Application.Run(frm);
    }
    catch (ThreadAbortException ex)
    {
        Thread.ResetAbort();
    }
}

Je l'ai utilisé la solution proposée par Fredrik Mörk. Il est très clair et élégant. Sinon, je trouve un problème si nous instancions la forme de démarrage avant de lancer l'application réelle (application.run (mainform ...)):

elle soulève une invalidOprationException provoquée par la forme poignée existe toujours pas dans l'appel-fil. Pour créer la poignée directement dans le fil t (et sauter cette exception!) Essayer de lancer le formulaire de démarrage de cette façon:

Thread t = new Thread(new ThreadStart(delegate
{
    _splash = new Splash();
     Application.Run(_splash);
}));

t.Start();

et, si vous prévoyez d'appeler la méthode closeSplash dans plusieurs branches du programme, forcer la valeur NULL après le premier appel:

    private static Splash _splash = null;
    public static void CloseSplash()
    {
        if (_splash!= null)
        {
            _splash.CloseSplash();
            _splash=null;
        }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top