繁体   English   中英

调试期间的 Visual Studio:function 评估需要所有线程运行

[英]Visual Studio during Debugging: The function evaluation requires all threads to run

调试时我突然遇到一个奇怪的错误。 至此手表windows中的变量已经正确显示。 现在我总是在手表 windows 中收到此错误消息:

function 评估需要所有线程运行

我无法再检查任何变量。 我没有明确地使用线程。 我该怎么做才能让它再次工作?

如某些论坛所述,我已经禁用了调试器选项 window 中的 function:“启用属性评估和其他隐式 function 调用”。 但没有成功,它给了我这个错误:

用户禁用的错误隐式 Function 评估

来自msdn论坛:

这本身不是错误,而是调试器的更多功能。 某些属性需要执行代码才能读取属性,但如果这需要跨线程交互,则其他线程可能也必须运行。 调试器不会自动执行此操作,但在您的许可下肯定可以。 只需单击小评估图标,它就会运行您的代码并评估属性。

在此处输入图片说明

有关此行为的更多详细信息,请查看这篇优秀文章

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

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

在此处输入图片说明

将鼠标悬停在调试模式下的机构上,单击以展开选项,然后单击结果会显示可怕的“函数评估需要所有线程运行”,并在末尾带有“请勿输入”图标,单击该图标后什么也没做。

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

  2. 解决方法 - 在调试选项中尝试不同的路径。 我发现我可以单击“非公共成员”>“_internalQuery”> ObjectQuery > Results View 并以这种方式获取我的值。

在此处输入图片说明

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

在此处输入图片说明

注意:我通过固定获得此图像,通常重新评估图标位于窗口中间而不是左侧列下方。

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

有关更多信息MSDN

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

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

现在我有一个 OtherThreadField 的值。

这不是错误,而是调试器的更多功能。
调试器不会自动执行此操作,但在用户许可的情况下肯定可以。 只需单击小空间图标,它就会运行代码并评估属性。

检查以下屏幕截图以供参考

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

对我来说,这发生在尝试中断访问设置 Class 包含的复杂 object 实例的行时。

以下if上的断点导致Settings.Default.FindSettings的值为“function 评估需要所有线程运行”。 如果我按下 force eval 按钮,它是 null。单击或不单击 force eval 按钮进入 if 块并初始化 object。如果我删除断点并在if块后添加一个新断点,即Settings.Default.FindSettings使用预期值正确反序列化。

if (Settings.Default.FindSettings == null)
{
    Settings.Default.FindSettings = new FindSettings();
}

经过反复试验,我在上面的if块之前添加了以下代码,以在中断之前访问设置。 这似乎可靠地解决了这个问题。 我在生产中不需要它,所以我包装在条件编译器指令中。 我在代码中有一个注释而不是一个非描述性的丢弃:

#if DEBUG
    var _ = Settings.Default.FindSettings;
#endif

我不确定上面的代码行是否会在生产中得到优化,因为它有副作用。 因为我只是在调试的时候需要,所以没有检查。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM