Je reçois soudainement une erreur étrange lors du débogage. Jusqu'à présent, la variable dans les fenêtres de surveillance était correctement affichée. 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 suis pas explicite de travailler avec des threads. Que puis-je faire pour que cela fonctionne à nouveau?
J'ai déjà désactivé, comme mentionné dans certains forums, la fonction: "Activer l'évaluation des propriétés et autres appels de fonction implicites" dans la fenêtre d'options du débogueur. Mais sans succès, alors j'obtiens l'erreur:
Erreur Evaluation de la fonction implicite désactivée par l'utilisateur
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 d'un code pour que la propriété puisse être lue, mais si cela nécessite une interaction entre threads, il est possible que d'autres threads doivent également s'exécuter. Le débogueur ne le fait pas automatiquement, mais peut certainement, avec votre permission. Il suffit de cliquer sur la petite icône d'évaluation pour lancer votre code et évaluer la propriété.
Pour plus de détails sur ce comportement, consultez cet excelent article
J'ai rencontré ce problème lorsque j'essayais simplement d'obtenir des éléments d'une table appelée "AGENCY" à l'aide d'Entity Framework:
var agencies = db.AGENCY.OrderBy(e => e.FULLNAME);
En survolant les agences en mode débogage, en cliquant pour développer les options, et en cliquant sur Résultats, vous obtiendrez le message redouté "L'évaluation de la fonction nécessite l'exécution de tous les threads" avec une icône "Ne pas entrer" à la fin, sur laquelle cliquer n'a fait rien.
2 solutions possibles:
Ajouter .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 en revient à HP93 de m'avoir aidé à trouver cette solution. Dans les commentaires sur la réponse de MUG4N où j'ai trouvé cette solution, il est également mentionné d'essayer .Any()
au lieu de .ToList()
, mais cela donne un booléen au lieu d'un <T>
, Comme <AGENCY>
L'est, donc cela ne vous aiderait probablement pas.
Solution de contournement - essayez un autre chemin dans les options de débogage. J'ai découvert que je pouvais cliquer sur "Afficher les résultats non publics"> "_internalQuery"> ObjectQuery> Results et obtenir ainsi mes valeurs.
MUG4N a bien fourni une réponse correcte, cependant, si vous passez la souris sur la ligne de code dans le débogage, il se peut que vous regardiez quelque chose comme ce qui suit. Si c'est le cas, cliquez sur la petite icône de réévaluation mise en surbrillance dans l'image ci-dessous ...
[~ # ~] nb [~ # ~] : j'ai obtenu cette image en épinglant, normalement les icones de réévaluation sont au milieu de la fenêtre. et pas dans la colonne de gauche.
Vous devez effectuer un appel thread-safe car l'accès aux contrôles de formulaire Windows n'est pas Thread safe en multithreading. C’est mon code simple qui fait de Thread un appel sécurisé 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
J'utilise la prochaine solution de contournement pour passer:
var OtherThreadField = "";
Invoke(new MethodInvoker(delegate
{
OtherThreadField = ExecuteNeededMEthod();
}));
Maintenant, j'ai une valeur pour OtherThreadField.