调试期间的 VisualStudio: 函数计算要求运行所有线程

我在调试的时候突然出现了一个奇怪的错误。到目前为止,手表窗口中的变量一直显示正确。现在我总是在手表窗口中收到这个错误消息:

函数计算要求运行所有线程

我不能再检查任何变量了。我没有显式地使用线程。我要怎么做才能让它重新工作?

我已经禁用了一些论坛中提到的调试器选项窗口中的“启用属性评估和其他隐函数调用”功能。但是没有成功,它给了我这个错误:

用户禁用的错误隐函数评估

141591 次浏览

来自 我不知道论坛:

这本身并不是一个错误,而更像是调试器的一个特性。 有些属性需要执行代码才能读取,但是如果这需要跨线程交互,那么其他线程可能也必须运行。调试器不会自动执行此操作,但如果您允许,它当然可以这样做。 只需单击小的计算图标,它就会运行您的代码并计算属性。

enter image description here

有关此行为的进一步详细信息,请检查这个优秀的 文章

我使用下一个变通方法来通过:

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

现在我有一个值用于 OtherThreadField。

应进行线程安全调用,因为访问 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");
}
}

了解更多信息

MUG4N 确实提供了一个正确的答案,但是如果您在调试中将鼠标悬停在代码行上,您可能会看到类似下面这样的内容。如果是这样,点击下图中突出显示的重新评估图标..。

enter image description here

注意 : 我是通过固定获得这张图片的,通常重新评估的图标位于窗口的中间,而不是左边的列。

我在试图使用实体框架(Entity Framework)从一个名为“ AGENCY”的表中获取项目时遇到了这个问题:

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

enter image description here

将鼠标悬停在调试模式下的代理上,单击以展开选项,然后单击 Results 将会出现令人恐惧的“函数计算需要所有线程运行”,最后有一个“ Do Not Enter”图标,单击这个图标什么也没有做。

2种可能的解决办法:

  1. 最后加入 .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 的答案的评论中,它也提到尝试 .Any()而不是 .ToList(),但是这给出了一个布尔值而不是 <T>,就像 <AGENCY>一样,所以它可能不会有什么帮助。

  2. 解决方案-在调试选项中尝试不同的路径。我发现我可以点击“非公共成员”> “ _ interalQuery”> ObjectQuery > Results View 并通过这种方式获得我的值。

enter image description here

这不是一个错误,而更像是调试器的一个特性。
调试器不会自动执行此操作,但在有用户权限的情况下肯定可以这样做。只要单击小空间图标,它就会运行代码并计算属性。

Check below screenshot for reference

我遇到了同样的问题并且解决了。问题出现是由于用户名和密码,在 SQL 连接中有用户和密码,但在代码中没有用户和密码。所以我启用了用户和密码并解决了问题