访问win窗体控件仅在Visual Studio中从不同的线程抛出异常

时间:2016-01-12 17:36:17

标签: c# .net winforms

我的知识是访问UI控件会抛出异常(如果是) 从不是创建它的线程(UI线程)的线程访问。

我得到的代码在访问简单属性时不会抛出异常 在带有调试器的Visual Studio中运行时的UI控件。

            var name = comboBox1.Name;
            var m1 = comboBox1.Items[1].ToString();

访问ComboBox的SelectedIndex时会这样做。

            comboBox1.SelectedItem.ToString();

运行没有调试器的相同代码不会抛出异常? 双击exe时同样的行为,没有例外吗?

为什么只有在附加调试器的情况下运行代码时才会出现异常 在没有调试器的情况下运行(Ctrl + F5)?

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        comboBox1.Items.Add("one");
        comboBox1.Items.Add("two");
        comboBox1.Items.Add("three");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            var name = comboBox1.Name;
            var m1 = comboBox1.Items[1].ToString();

            MessageBox.Show(comboBox1.SelectedItem.ToString(), "MM");
        });
    }
}

3 个答案:

答案 0 :(得分:2)

它在调试器中可靠地发生,因为visual studio足够聪明"查看错误并强制它始终发生,以防止在运行时出现神秘的间歇性错误。这是Visual Studio中包含的许多Managed Debug Assistants之一。它可以帮助您通过将其转换为一致的错误来发现间歇性错误。

基本上,从另一个线程访问UI控件总是错误的做法,但Windows并不总是抛出错误,有时它会继续没有任何问题。调试时MDA处于活动状态。它专门监视对UI的跨线程访问,并确保始终发生错误。

答案 1 :(得分:0)

您最终可能会在调试器外部看到异常。请记住,由于附加了断点等,调试器可以在线程相互交互时进行更改。

这只是一个概率问题 - 附加调试器会改变执行特性,这样在您的情况下,您更有可能看到线程以有问题的方式进行交互。反之亦然。

特别是因为你正在使用Task api(它不会必然为每个后台执行生成一个新线程),所以在大多数情况下你甚至可能不会生成一个新线程(如果你很好奇这是如何工作的,你可以看一下“工作窃取算法”)

答案 2 :(得分:0)

我决定在这里发帖后得到答案:)

https://msdn.microsoft.com/en-us/library/ms171728.aspx

在调试期间以及在某些情况下,在运行时可靠地发生此异常。

所以我的用例不在: “在某些情况下,在运行时”

我希望这可以帮助那些遇到同样问题的人。