Nagle pojawia się dziwny błąd podczas debugowania. Do tej pory zmienna w oknach obserwacyjnych była wyświetlana poprawnie. Teraz w oknach zegarka zawsze pojawia się komunikat o błędzie:
Ocena funkcji wymaga działania wszystkich wątków
Nie mogę już sprawdzić żadnej zmiennej. Nie jestem jawny w pracy z wątkami. Co mogę zrobić, aby znów działał?
Wyłączyłem już, jak wspomniano na niektórych forach, funkcję: "Włącz ocenę właściwości i inne niejawne wywołania funkcji" w oknie opcji debuggera. Ale bez powodzenia otrzymuję błąd:
Niejawna ocena funkcji błędu wyłączona przez użytkownika
Odpowiedzi:
Z forum MSDN :
Więcej informacji na temat tego zachowania można znaleźć w tym znakomitym artykule
źródło
.ToList()
lub.Any()
.var
aIEnumerable<T>
i właśnie przypisaniedb.AGENCY_TABLE.OrderBy(e => e.Name);
- ale raz użyłemvar
z.ToList()
(lubList<T>
z.ToList()
działa również), to ujawnia wynik!Napotkałem ten problem, próbując po prostu pobrać elementy z tabeli o nazwie „AGENCY” za pomocą Entity Framework:
var agencies = db.AGENCY.OrderBy(e => e.FULLNAME);
Najechanie kursorem na agencje w trybie debugowania, kliknięcie, aby rozwinąć opcje, i kliknięcie Wyniki dałoby przerażające „Ocena funkcji wymaga uruchomienia wszystkich wątków” z ikoną „Nie wchodź” na końcu, na której kliknięcie nic nie dało.
2 możliwe rozwiązania:
Dodaj
.ToList()
na końcu:var agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();
List<AGENCY_TABLE> agencies = db.AGENCY_TABLE.OrderBy(e => e.FULLNAME).ToList();
Podziękowania dla Hp93 za pomoc w znalezieniu tego rozwiązania. W komentarzach do odpowiedzi MUG4N, w której znalazłem to rozwiązanie, wspomina również o próbowaniu
.Any()
zamiast.ToList()
, ale to daje wartość logiczną zamiast<T>
, jak<AGENCY>
jest, więc prawdopodobnie nie pomoże.Obejście - wypróbuj inną ścieżkę w opcjach debugowania. Okazało się, że mogę kliknąć „Członkowie niepubliczni”> „_internalQuery”> ObjectQuery> Widok wyników i uzyskać w ten sposób moje wartości.
źródło
MUG4N rzeczywiście dostarczył poprawną odpowiedź, jednak jeśli najedziesz kursorem na wiersz kodu w debugowaniu, możesz patrzeć na coś podobnego do poniższego. Jeśli tak, kliknij małą ikonę ponownej oceny podświetloną na poniższym obrazku ...
NB : Otrzymałem ten obraz przez przypięcie, zwykle ponownie oceniam ikonę w środku okna, a nie w lewej kolumnie.
źródło
Powinieneś wykonać bezpieczne wywołanie wątku, ponieważ dostęp do formantów formularzy systemu Windows nie jest bezpieczny dla wątków w wielowątkowości. To jest mój prosty kod, który sprawia, że wątek jest bezpieczny i ustawia pasek postępu.
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"); } }
Po więcej informacji MSDN
źródło
Używam następnego obejścia, aby przejść:
var OtherThreadField = ""; Invoke(new MethodInvoker(delegate { OtherThreadField = ExecuteNeededMEthod(); }));
Teraz mam wartość dla OtherThreadField.
źródło