调试期间的Visual Studio:函数评估需要所有线程才能运行


92

调试时突然出现一个奇怪的错误。到目前为止,监视窗口中的变量已正确显示。现在,我总是在监视窗口中看到错误消息:

函数评估要求所有线程都运行

我无法检查任何变量了。我没有明确使用线程。我该怎么做才能使其恢复正常工作?

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

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


要获得清单的重点:您是否重新启动了Visual Studio?
MUG4N

是的,我做到了。重新启动,同样的问题。
迈克(Maik),2015年


即使可行,这也不是解决方案,因为我想使用NET 4.x框架。我不想因为这个问题而降级。我想知道为什么它在一段时间前起作用。
迈克(Maik),2015年

我有同样的问题。VS2013有一个可以单击的按钮,但VS2015没有此按钮。
Spongman

Answers:


112

msdn论坛:

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

在此处输入图片说明

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


9
我确实读过这篇文章。我没有这样的按钮可以单击,所以不完全是我遇到的问题。奇怪的是,自从我今天升级到Visual Studio 2015 RC以来,它一直在工作。
迈克(Maik)


4
如果看不到任何图标,请尝试修改变量/命令以从监视窗口执行查询,而不要使用下拉列表来浏览其属性。例如,添加.ToList().Any()
Hp93

4
我不确定为什么,但是在查询中调用.ToList()解决了该问题
J.Kirk。

1
@J。柯克 我发现了同一件事-谢谢!使用我已经varIEnumerable<T>公正分配db.AGENCY_TABLE.OrderBy(e => e.Name);-可是一旦我用var.ToList()(或List<T>.ToList()同样适用),它揭示的结果!
vapcguy

23

当尝试使用实体框架从名为“ 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答案的评论中,它还提到了try.Any()而不是.ToList(),但这<T><AGENCY>is is那样提供了Boolean而不是a ,所以它可能无济于事。

  2. 解决方法-在调试选项中尝试其他路径。我发现可以单击“非公共成员”>“ _ internalQuery”>“ ObjectQuery”>“结果视图”,并以此方式获取值。

在此处输入图片说明


9

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

在此处输入图片说明

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


这帮了我大忙。不能相信我没有尝试过,谢谢您的回答。
petey m

2

您应该进行线程安全调用,因为在多线程中访问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


1

我使用下一个解决方法:

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

现在我有一个OtherThreadField的值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.