Visual Studio під час налагодження: оцінка функції вимагає запуску всіх потоків


93

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

Оцінка функції вимагає запуску всіх потоків

Я більше не можу перевірити жодну змінну. Я не явно працюю з потоками. Що я можу зробити, щоб він знову запрацював?

Я вже відключив, як згадувалося на деяких форумах, функцію: "Увімкнути оцінку властивостей та інші неявні виклики функцій" у вікні параметрів налагоджувача. Але без успіху, тоді я отримую помилку:

Оцінка неявної функції помилки відключена користувачем


Щоб зрозуміти цю точку списку: Ви перезапустили Visual Studio?
MUG4N

Так. Перезапущено та ж проблема.
Майк


Навіть якщо це спрацює, це не може бути рішенням, оскільки я хочу використовувати NET 4.x Framework. Я не хочу знижувати рейтинг лише тому, що якщо це питання. Мені цікаво, чому це працювало деякий час тому.
Майк

у мене така ж проблема. У VS2013 була кнопка, яку ви можете натиснути, але у VS2015 цієї кнопки немає.
Spongman

Відповіді:


113

З форуму msdn :

Це не помилка сама по собі, а більше властивість вашого налагоджувача. Деякі властивості вимагають виконання коду для читання властивості, але якщо для цього потрібна взаємодія між потоками, можливо, доведеться запустити й інші потоки. Налагоджувач не робить це автоматично, але, звичайно, може з вашого дозволу. Просто натисніть маленький значок оцінки, і він запустить ваш код і оцінить властивість.

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

Для отримання детальної інформації про цю поведінку перегляньте цю чудову статтю


9
Я прочитав цю статтю. У мене немає такої кнопки, щоб натиснути, тому не зовсім у мене проблема. Досить дивно, що він працював, оскільки сьогодні я перейшов на Visual Studio 2015 RC.
Майк

1
Те ж питання тут: stackoverflow.com/questions/4460206 / ...
MUG4N

4
Якщо ви не бачите жодної піктограми, спробуйте змінити змінну / команду, щоб виконати запит із вікна годинника, замість того, щоб використовувати спадне меню, щоб дослідити його властивості. Наприклад, додавання .ToList()або .Any().
Hp93

4
Я не впевнений, чому, але виклик .ToList () з мого запиту
вирішив

1
@ J.Kirk. Я знайшов те саме - дякую! Я використовував varі IEnumerable<T>і тільки призначення db.AGENCY_TABLE.OrderBy(e => e.Name);- але як тільки я varз .ToList()(або List<T>з .ToList()теж працює), він показує результат!
vapcguy

23

Я зіткнувся з цією проблемою, коли просто намагався отримати елементи з таблиці під назвою "АГЕНТСТВО" за допомогою 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> Перегляд результатів і отримати мої значення таким чином.

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


9

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

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

NB : Я отримав це зображення закріпленням, як правило, повторна оцінка icone знаходиться в середині вікна, а не в лівій колонці.


Це зробило для мене фокус. Не можу повірити, що я цього не пробував, дякую за відповідь.
petey m

2

Ви повинні здійснити безпечний виклик потоку, оскільки доступ до елементів керування формою Windows не є безпечним для потоків у багатопотоковості. Це мій простий код, який робить Thread безпечним викликом і встановлює індикатор прогресу.

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.