簡體   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