Visual Studio ระหว่างการดีบัก: การประเมินฟังก์ชันต้องการเธรดทั้งหมดเพื่อรัน


93

จู่ๆฉันก็ได้รับข้อผิดพลาดแปลก ๆ ขณะทำการดีบัก ถึงตอนนี้ตัวแปรในหน้าต่างนาฬิกาแสดงอย่างถูกต้อง ตอนนี้ฉันมักจะได้รับข้อความแสดงข้อผิดพลาดในหน้าต่างนาฬิกา:

การประเมินฟังก์ชันต้องการเธรดทั้งหมดเพื่อรัน

ฉันไม่สามารถตรวจสอบตัวแปรใด ๆ ได้อีกต่อไป ฉันไม่ได้ทำงานกับเธรดอย่างชัดเจน ฉันจะทำอย่างไรเพื่อให้มันใช้งานได้อีกครั้ง

ฉันปิดการใช้งานแล้วดังที่กล่าวไว้ในบางฟอรัมฟังก์ชัน: "เปิดใช้งานการประเมินคุณสมบัติและการเรียกฟังก์ชันโดยนัยอื่น ๆ " ในหน้าต่างตัวเลือกของดีบักเกอร์ แต่ไม่ประสบความสำเร็จฉันได้รับข้อผิดพลาด:

ข้อผิดพลาดโดยนัยการประเมินฟังก์ชันถูกปิดใช้งานโดยผู้ใช้


ในการรับจุดนั้นของรายการ: คุณได้รีสตาร์ท Visual Studio แล้วหรือยัง?
MUG4N

ใช่ฉันทำ. รีสตาร์ทและเป็นปัญหาเดียวกัน
Maik

ตรวจสอบสิ่งนี้: stackoverflow.com/questions/4280604/…
MUG4N

แม้ว่าจะใช้งานได้ แต่ก็ไม่สามารถแก้ปัญหาได้เนื่องจากฉันต้องการใช้ NET 4.x Framework ฉันไม่ต้องการที่จะปรับลดเพียงเพราะถ้าปัญหานี้ ฉันสงสัยว่าทำไมมันถึงใช้งานได้ในช่วงที่ผ่านมา
Maik

ฉันมีปัญหาเดียวกัน VS2013 มีปุ่มที่คุณสามารถคลิกได้ แต่ VS2015 ไม่มีปุ่มนี้
Spongman

คำตอบ:


113

จากฟอรัมmsdn :

นี่ไม่ใช่ข้อผิดพลาดในตัวมันเอง แต่เป็นคุณลักษณะของโปรแกรมแก้ไขข้อบกพร่องของคุณ คุณสมบัติบางอย่างจำเป็นต้องมีการเรียกใช้โค้ดเพื่อให้สามารถอ่านคุณสมบัติได้ แต่ถ้าสิ่งนี้ต้องการการโต้ตอบข้ามเธรดเธรดอื่น ๆ ก็อาจต้องทำงานด้วยเช่นกัน ดีบักเกอร์ไม่ได้ทำสิ่งนี้โดยอัตโนมัติ แต่ทำได้แน่นอนเมื่อได้รับอนุญาตจากคุณ เพียงคลิกไอคอนประเมินเล็ก ๆ น้อย ๆ จากนั้นจะเรียกใช้โค้ดของคุณและประเมินคุณสมบัติ

ป้อนคำอธิบายภาพที่นี่

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับพฤติกรรมนี้โปรดดูบทความที่ยอดเยี่ยมนี้


9
ฉันอ่านบทความนี้ ฉันไม่มีปุ่มให้คลิกจึงไม่ใช่ปัญหาที่ฉันมี ที่แปลกก็คือมันใช้งานได้ตั้งแต่ฉันได้อัปเกรดเป็น Visual Studio 2015 RC ในวันนี้
Maik

1
ฉบับเดียวกันที่นี่: stackoverflow.com/questions/4460206/…
MUG4N

4
หากคุณไม่เห็นไอคอนใด ๆ ให้ลองแก้ไขตัวแปร / คำสั่งเพื่อดำเนินการสืบค้นจากหน้าต่างนาฬิกาแทนที่จะใช้เมนูแบบเลื่อนลงเพื่อสำรวจคุณสมบัติ ตัวอย่างเช่นการเพิ่มหรือ.ToList() .Any()
Hp93

4
ฉันไม่แน่ใจว่าทำไม แต่การโทร. toList () ในแบบสอบถามของฉันช่วยแก้ปัญหาได้
J.Kirk

1
@ เจ. เคิร์ก. ฉันพบสิ่งเดียวกัน - ขอบคุณ! ฉันเคยใช้varและIEnumerable<T>และแค่มอบหมายdb.AGENCY_TABLE.OrderBy(e => e.Name);- แต่เมื่อฉันใช้varกับ.ToList()(หรือList<T>ใช้.ToList()งานได้ด้วย) มันเผยให้เห็นผลลัพธ์!
vapcguy

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> มุมมองผลลัพธ์และรับค่าของฉันด้วยวิธีนั้น

ป้อนคำอธิบายภาพที่นี่


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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.