Visual Studio во время отладки: оценка функции требует запуска всех потоков.

93

При отладке внезапно появляется странная ошибка. До сих пор переменная в окнах просмотра отображалась правильно. Теперь я всегда получаю сообщение об ошибке в окнах часов:

Оценка функции требует, чтобы все потоки работали

Я больше не могу проверить какие-либо переменные. Я не работаю с потоками явно. Что я могу сделать, чтобы он снова заработал?

Я уже отключил, как упоминалось на некоторых форумах, функцию: «Включить оценку свойств и другие неявные вызовы функций» в окне параметров отладчика. Но без успеха я получаю сообщение об ошибке:

Ошибка Неявная оценка функции отключена пользователем

Maik
источник
Чтобы понять этот пункт списка: вы перезапустили Visual Studio?
MUG4N
Да. Перезагрузка и та же проблема.
Maik
проверьте это: stackoverflow.com/questions/4280604/…
MUG4N
Даже если бы это сработало, это не может быть решением, так как я хочу использовать NET 4.x Framework. Я не хочу понижать только потому, что это проблема. Мне интересно, почему это работало некоторое время назад.
Maik
У меня такая же проблема. VS2013 имел кнопку, которую можно было щелкнуть, но VS2015 не имеет этой кнопки.
Spongman

Ответы:

113

С форума msdn :

Это не ошибка сама по себе, а скорее функция вашего отладчика. Некоторые свойства требуют выполнения кода, чтобы свойство было прочитано, но если это требует взаимодействия между потоками, тогда, возможно, придется запускать и другие потоки. Отладчик не делает это автоматически, но, конечно, может с вашего разрешения. Просто щелкните маленький значок оценки, и он запустит ваш код и оценит свойство.

введите описание изображения здесь

Дополнительные сведения об этом поведении см. В этой отличной статье.

MUG4N
источник
9
Я прочитал эту статью. У меня нет такой кнопки, поэтому у меня не совсем та проблема. Как ни странно, он работал с тех пор, как я сегодня обновился до Visual Studio 2015 RC.
Майк
1
Такая же проблема здесь: stackoverflow.com/questions/4460206/…
MUG4N
4
Если вы не видите никакого значка, попробуйте изменить переменную / команду для выполнения запроса из окна просмотра, вместо использования раскрывающегося списка для изучения ее свойств. Например, добавление .ToList()или .Any().
Hp93
4
Я не уверен, почему, но вызов .ToList () в моем запросе устранил проблему
Дж. Кирк.
1
@ Дж. Кирк. Нашел то же самое - спасибо! Я использовал varи IEnumerable<T>просто назначал db.AGENCY_TABLE.OrderBy(e => e.Name);- но как только я использовал varс .ToList()(или List<T>с .ToList()тоже работает), это показывает результат!
vapcguy 05
23

Я столкнулся с этой проблемой, когда просто пытался получить элементы из таблицы под названием «AGENCY» с помощью Entity Framework:

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, где я нашел это решение, также упоминается попытка .Any()вместо .ToList(), но это дает логическое значение вместо <T>, как <AGENCY>есть, поэтому это, вероятно, не поможет.

  2. Обходной путь - попробуйте другой путь в параметрах отладки. Я обнаружил, что могу щелкнуть «Непубличные члены»> «_internalQuery»> ObjectQuery> Просмотр результатов и получить таким образом свои значения.

введите описание изображения здесь

vapcguy
источник
9

MUG4N действительно дал правильный ответ, однако, если вы наведете курсор на строку кода во время отладки, вы можете увидеть что-то вроде следующего. Если да, щелкните маленький значок повторной оценки, выделенный на изображении ниже ...

введите описание изображения здесь

NB : Я получил это изображение путем закрепления, обычно значок переоценки находится в середине окна, а не в левом столбце.

Ewan
источник
Это помогло мне. Не могу поверить, что я не пробовал это, спасибо за ответ.
Пити М.
2

Вы должны сделать потокобезопасный вызов, потому что доступ к элементам управления формы Windows не является потокобезопасным при многопоточности. Это мой простой код, который делает вызов Thread-safe и устанавливает индикатор выполнения.

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.

sh2dow
источник