我的知识是访问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");
});
}
}
答案 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
在调试期间以及在某些情况下,在运行时可靠地发生此异常。
所以我的用例不在: “在某些情况下,在运行时”
我希望这可以帮助那些遇到同样问题的人。