Visual Studio pendant le débogage: l'évaluation de la fonction nécessite que tous les threads s'exécutent

93

Je reçois soudainement une erreur étrange lors du débogage. Jusqu'à présent, la variable dans les fenêtres de surveillance a été affichée correctement. Maintenant, je reçois toujours le message d'erreur dans les fenêtres de surveillance:

L'évaluation de la fonction nécessite l'exécution de tous les threads

Je ne peux plus vérifier aucune variable. Je ne travaille pas explicitement avec des threads. Que puis-je faire pour qu'il fonctionne à nouveau?

J'ai déjà désactivé comme mentionné dans certains forums la fonction: "Activer l'évaluation de propriété et d'autres appels de fonction implicites" dans la fenêtre d'options du débogueur. Mais sans succès, j'obtiens l'erreur:

Erreur Évaluation de la fonction implicite désactivée par l'utilisateur

Maik
la source
Pour obtenir ce point de la liste: avez-vous redémarré Visual Studio?
MUG4N
Oui je l'ai fait. Redémarré et même problème.
Maik
Même si cela fonctionnait, cela ne peut pas être la solution, car je souhaite utiliser le Framework NET 4.x. Je ne veux pas rétrograder simplement parce que si ce problème. Je me demande pourquoi cela fonctionnait il y a quelque temps.
Maik
J'ai le même problème. VS2013 avait un bouton sur lequel vous pouviez cliquer, mais VS2015 n'a pas ce bouton.
Spongman

Réponses:

113

Depuis le forum msdn :

Ce n'est pas une erreur en soi, mais plutôt une fonctionnalité de votre débogueur. Certaines propriétés nécessitent l'exécution de code pour que la propriété soit lue, mais si cela nécessite une interaction entre threads, d'autres threads devront peut-être s'exécuter également. Le débogueur ne le fait pas automatiquement, mais le peut certainement, avec votre permission. Cliquez simplement sur la petite icône d'évaluation et il exécutera votre code et évaluera la propriété.

entrez la description de l'image ici

Pour plus de détails sur ce comportement, consultez cet excellent article

MUG4N
la source
9
J'ai lu cet article. Je n'ai pas un tel bouton sur lequel cliquer, donc pas exactement le problème que j'ai. C'est assez étrange, que cela fonctionnait depuis que j'ai mis à niveau vers Visual Studio 2015 RC aujourd'hui.
Maik
1
Même problème ici: stackoverflow.com/questions/4460206/…
MUG4N
4
Si vous ne voyez aucune icône, essayez de modifier la variable / commande pour exécuter la requête à partir de la fenêtre de surveillance, au lieu d'utiliser le menu déroulant pour explorer ses propriétés. Par exemple, ajouter .ToList()ou .Any().
Hp93
4
Je ne sais pas pourquoi mais appeler .ToList () sur ma requête a résolu le problème
J.Kirk.
1
@ J.Kirk. J'ai trouvé la même chose - merci! J'avais utilisé varet IEnumerable<T>et juste assigner db.AGENCY_TABLE.OrderBy(e => e.Name);- mais une fois que j'ai utilisé varavec .ToList()(ou List<T>avec .ToList()aussi des œuvres), cela révèle le résultat!
vapcguy
23

J'ai rencontré ce problème en essayant simplement d'obtenir des éléments d'une table appelée "AGENCY" en utilisant Entity Framework:

var agencies = db.AGENCY.OrderBy(e => e.FULLNAME);

entrez la description de l'image ici

Survoler les agences en mode débogage, cliquer pour développer les options et cliquer sur Résultats donnerait le redouté "L'évaluation de la fonction nécessite que tous les threads s'exécutent" avec une icône "Ne pas entrer" à la fin qui, sur laquelle, cliquer n'a rien fait.

2 solutions possibles:

  1. Ajoutez .ToList()à la fin:

    var agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();

    List<AGENCY_TABLE> agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();

    Le mérite revient à Hp93 pour m'avoir aidé à trouver cette solution. Dans les commentaires sur la réponse de MUG4N où j'ai trouvé cette solution, il mentionne également essayer .Any()au lieu de .ToList(), mais cela donne un booléen au lieu d'un <T>, comme <AGENCY>est, donc cela n'aiderait probablement pas.

  2. Solution de contournement - essayez un chemin différent dans les options de débogage. J'ai trouvé que je pouvais cliquer sur "Membres non publics"> "_internalQuery"> ObjectQuery> Affichage des résultats et obtenir mes valeurs de cette façon.

entrez la description de l'image ici

vapcguy
la source
9

MUG4N a en effet fourni une réponse correcte, mais si vous survolez la ligne de code dans le débogage, vous pouvez regarder quelque chose comme ci-dessous. Si tel est le cas, cliquez sur la petite icône de réévaluation en surbrillance dans l'image ci-dessous ...

entrez la description de l'image ici

NB : j'ai obtenu cette image en épinglant, normalement les icones de réévaluation sont au milieu de la fenêtre et non en bas de la colonne de gauche.

Ewan
la source
Cela a fait l'affaire pour moi. Je ne peux pas croire que je n'ai pas essayé cela, merci pour la réponse.
Petey
2

Vous devez effectuer un appel thread-safe car l'accès aux contrôles de formulaire Windows n'est pas thread-safe en multithreading. Ceci est mon code simple qui rend l'appel sûr de Thread et définit la barre de progression.

public partial class Form1 : Form
{// This delegate enables asynchronous calls for setting  
    // the text property on a TextBox control.  
    delegate void StringArgReturningVoidDelegate(string text);
    private Thread demoThread = null;

    public int Progresscount = 0;
    static EventWaitHandle waithandler = new AutoResetEvent(false);
    public Form1()
    {
        InitializeComponent();
    }
    public static bool CheckForInternetConnection()
    {
        try
        {


            using (var client = new WebClient())
            {
                using (var stream = client.OpenRead("http://www.google.com"))
                {
                    return true;
                }
            }
        }
        catch
        {
            return false;
        }
    }

    public  void Progressincrement()
    {

        waithandler.WaitOne();
        while (CheckForInternetConnection()==true)
        {
            if (Progresscount==100)

            {
                break;
            }
            SetLabel("Connected");
            Progresscount += 1;

       SetProgress(Progresscount.ToString());
            Thread.Sleep(TimeSpan.FromSeconds(1));
        }
        if (Progresscount <100)
        {
            Startthread();
        }
        SetLabel("Completed");


    }

  public  void Startthread ()
        {

   this.demoThread=   new Thread(new ThreadStart(Progressincrement));
        this.demoThread.Start();
     SetLabel("Waiting for connection");
        while (CheckForInternetConnection() == false) ;

        waithandler.Set();
    }
    private void SetLabel(string text)
    {
        // InvokeRequired required compares the thread ID of the  
        // calling thread to the thread ID of the creating thread.  
        // If these threads are different, it returns true.  
        if (this.label1.InvokeRequired)
        {
            StringArgReturningVoidDelegate d = new StringArgReturningVoidDelegate(SetLabel);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.label1.Text = text;
        }
    }
    private void SetProgress(string Value)
    {
        // InvokeRequired required compares the thread ID of the  
        // calling thread to the thread ID of the creating thread.  
        // If these threads are different, it returns true.  
        if (this.progressBar1.InvokeRequired)
        {
            StringArgReturningVoidDelegate d = new StringArgReturningVoidDelegate(SetProgress);
            this.Invoke(d, new object[] {Value});
        }
        else
        {
            this.progressBar1.Value = Convert.ToInt32(Value);
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        Startthread();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Responsive");
    }
}

Pour plus d'informations MSDN

TAHA SULTAN TEMURI
la source
1

J'utilise la solution de contournement suivante pour réussir:

var OtherThreadField = "";
Invoke(new MethodInvoker(delegate
                    {
                        OtherThreadField = ExecuteNeededMEthod();
                    }));

Maintenant, j'ai une valeur pour OtherThreadField.

sh2dow
la source