Question

Pour les besoins du raisonnement, considérons un thread d'interface utilisateur comme un fil qui a eu un appel à Application.Run() ou l'un de ses surcharges ont appelé et a un fonctionnement en boucle de message actif.

Y at-il un moyen de détecter si nous en cours d'exécution sur un tel fil?

La raison pour laquelle je veux c'est parce que j'ai une classe avec une fonction privée qui est de longue durée. La classe elle-même est déjà multithread, et l'utilisation de cette classe est telle qu'elle peut être utilisée soit de l'interface utilisateur ou de fils de fond faisant le traitement. Cette fonction tombe également dans ce filet. Mais je ne veux pas bloquer le thread d'interface utilisateur. Je veux donc détecter si je suis en cours d'exécution sur un thread d'interface utilisateur et si oui, fourchette l'appel de fonction dans un fil d'arrière-plan (probablement ThreadPool, mais c'est pas un problème pour cette discussion). Ceci est tout à fait bien comportés, mais les fils de fond sont probablement compte sur la sortie de la fonction, le blocage donc pour eux est mieux, alors que le thread d'interface utilisateur accède dans une manière plus « set-and-forget ».

Était-ce utile?

La solution

Je dirais que c'est le genre de décision que l'appelant doit faire. Vous pouvez toujours écrire des méthodes wrapper pour le rendre plus facile - mais cela signifie que vous ne serez pas avoir des problèmes avec l'appelant étant dans une situation « bizarre » (par exemple, un cadre de l'interface utilisateur que vous ne connaissez pas, ou autre chose avec une boucle d'événements ) et vous prendre la mauvaise décision pour eux.

Si la méthode doit toujours faire des commentaires dans le fil droit, je passe dans un ISynchronizeInvoke (mis en œuvre par Control) de le faire d'une manière de l'interface utilisateur-agnostique.

Autres conseils

Si vous avez accès à un Form ou un Control, vous pouvez vérifier le InvokeRequired propriété; cela retourne false si vous êtes sur le thread d'interface utilisateur et true si vous n'êtes pas .. Si cela se produit dans un contexte où vous ne pouvez pas vérifier contre un Control, vous pouvez facilement mettre en place une propriété statique dans votre programme que vous pouvez vérifier contre. Conservez une référence à Thread.CurrentThread au démarrage et comparer Thread.CurrentThread à cette référence lorsque vous devez savoir:

static class Program
{
    private static Thread _startupThread = null;

    [STAThread]
    static void Main()
    {
        _startupThread = Thread.CurrentThread;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public static bool IsRunningOnStartupThread()
    {
        return Thread.CurrentThread == _startupThread;
    }
}

En appelant Program.IsRunningOnStartupThread vous obtiendrez un bool dire si vous êtes ou non.

bool isMessageLoopThread = System.Windows.Forms.Application.MessageLoop;

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top