C# 调试期间的 Visual Studio:函数评估需要所有线程运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29985150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Visual Studio during Debugging: The function evaluation requires all threads to run
提问by Maik
I'm getting suddenly a strange error while debugging. Up to now the variable in the watch windows has been shown correctly. Now I am getting always the error message in the watch windows:
调试时我突然收到一个奇怪的错误。到目前为止,观察窗口中的变量已正确显示。现在我总是在监视窗口中收到错误消息:
The function evaluation requires all threads to run
函数求值需要所有线程运行
I am not able to check any variable anymore. I am not explicit working with threads. What can I do to get it working again?
我无法再检查任何变量。我不是明确地使用线程。我该怎么做才能让它再次工作?
I disabled already as mentioned in some forums the function: "Enable property Evaluation and other implicit function Calls" in the option window of the debugger. But without success, then I am getting the error:
我已经禁用了某些论坛中提到的功能:调试器选项窗口中的“启用属性评估和其他隐式函数调用”。但没有成功,然后我收到错误:
Error Implicit Function evaluation disabled by the user
用户禁用了错误隐式函数评估
回答by MUG4N
From the msdnforum:
来自msdn论坛:
This isn't an error in and of itself, but more of a feature of your debugger. Some properties require code to be executed in order for the property to be read, but if this requires cross-thread interaction, then other threads may have to run as well. The debugger doesn't do this automatically, but certainly can, with your permission. Just click the little evaluate icon and it will run your code and evaluate the property.
这本身不是错误,而是调试器的更多功能。某些属性需要执行代码才能读取属性,但如果这需要跨线程交互,则其他线程可能也必须运行。调试器不会自动执行此操作,但在您的许可下肯定可以。只需单击评估小图标,它就会运行您的代码并评估属性。


For further details on this behaviour check this excelent article
有关此行为的更多详细信息,请查看这篇优秀文章
回答by sh2dow
I use the next workaround to pass:
我使用下一个解决方法来通过:
var OtherThreadField = "";
Invoke(new MethodInvoker(delegate
{
OtherThreadField = ExecuteNeededMEthod();
}));
Now i have a value for OtherThreadField.
现在我有一个 OtherThreadField 的值。
回答by TAHA SULTAN TEMURI
You should make thread safe call because accessing Windows form controls are not Thread safe in multithreading. This is my simple code which makes Thread safe call and sets Progress bar.
您应该进行线程安全调用,因为访问 Windows 窗体控件在多线程中不是线程安全的。这是我的简单代码,它使线程安全调用并设置进度条。
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");
}
}
For more information MSDN
有关更多信息MSDN
回答by Ewan
MUG4N has indeed provided a correct answer however if you hover over the line of code in debug, you may be looking at something like the below. If so, click the little re-evaluate icon highlighted in the image below...
MUG4N 确实提供了正确的答案,但是如果您将鼠标悬停在调试中的代码行上,您可能会看到如下所示的内容。如果是这样,请单击下图中突出显示的小重新评估图标...
NB: I obtained this image by pinning, normally the re-evaluate icone are in the middle of the window and not down the left hand column.
注意:我通过固定获得此图像,通常重新评估图标位于窗口中间而不是左侧列下方。
回答by vapcguy
I ran into this issue when just trying to get items from a table called "AGENCY" using Entity Framework:
我在尝试使用实体框架从名为“AGENCY”的表中获取项目时遇到了这个问题:
var agencies = db.AGENCY.OrderBy(e => e.FULLNAME);
Hovering over agencies in debug mode, clicking to expand the options, and clicking Results would give the dreaded "The function evaluation requires all threads to run" with a "Do Not Enter" icon at the end that, on which, clicking did nothing.
将鼠标悬停在调试模式下的机构上,单击以展开选项,然后单击结果会显示可怕的“函数评估需要所有线程运行”,并在末尾带有“请勿输入”图标,单击该图标后什么也没做。
2 possible solutions:
2种可能的解决方案:
Add
.ToList()at the end:var agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();List<AGENCY_TABLE> agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();Credit goes to Hp93 for helping me come to this solution. In the comments on MUG4N's answer where I found this solution, it also mentions trying
.Any()instead of.ToList(), but this gives a Boolean instead of a<T>, like<AGENCY>is, so it probably wouldn't help.Workaround - try a different path in the debug options. I found that I could click on the "Non-Public Members" > "_internalQuery" > ObjectQuery > Results View and get my values that way.
.ToList()在最后添加:var agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();List<AGENCY_TABLE> agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();感谢 Hp93 帮助我找到了这个解决方案。在我找到此解决方案的 MUG4N 答案的评论中,它还提到了 try
.Any()而不是.ToList(),但这给出了一个布尔值而不是一个<T>,就像<AGENCY>是一样,所以它可能无济于事。解决方法 - 在调试选项中尝试不同的路径。我发现我可以单击“非公共成员”>“_internalQuery”> ObjectQuery > Results View 并以这种方式获取我的值。

