问题:使用多线程操作控件出现“线程间操作无效: 从不是创建控件“comboBox1”的线程访问它。”
原因:微软因为安全原因不允许不是同一个线程中操作控件,只允许同一个线程或进程中操作。
解决:1.使用控件的Invoke()方法解决
2.放入窗体的构造函数中,“InitializeComponent()”方法后执行
以下是使用控件Invoke()方法解决:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
//问题:使用多线程操作控件出现“线程间操作无效: 从不是创建控件“comboBox1”的线程访问它。”
//原因:微软因为安全原因不允许不是同一个线程中操作控件,只允许同一个线程或进程中操作。
//解决:1.使用控件的Invoke方法解决
// 2.放入窗体的构造函数中,“InitializeComponent()”方法后执行
//Step 1: 定义委托
delegate void SetComboxBoxCallback(List<DataModel> list);
//Step 2: 定义更新UI控件方法
private void AddDataToComboxBox(List<DataModel> list)
{
//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.comboBox1.InvokeRequired)//如果调用控件的线程和创建创建控件的线程不是同一个则为True
{
while (!this.comboBox1.IsHandleCreated)
{
//解决窗体关闭时出现“访问已释放句柄“的异常
if (this.comboBox1.Disposing || this.comboBox1.IsDisposed)
return;
}
SetComboxBoxCallback method = new SetComboxBoxCallback(AddDataToComboxBox);
this.comboBox1.Invoke(method, new object[] { list });
//绑定数据到指定DataGridView
//this.dgv.Invoke(new EventHandler(delegate
//{
//dgv.DataSource = list;
//}));
//绑定到多个控件
//this.Invoke(new EventHandler(delegate
//{
//cmbQuestionType.DataSource = list;
//cmbQuestionType1.DataSource = list;
//}));
}
else
{
comboBox1.Items.AddRange(list.ToArray());
}
}
//Step 3 定义异步执行方法
private void SyncLoadComboxBox()
{
Task.Factory.StartNew(() =>
{
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "ID";
comboBox1.Sorted = true;
List<DataModel> dataList = new List<DataModel>();
dataList.Add(new DataModel() { ID = 1, Name = "阿里巴巴" });
dataList.Add(new DataModel() { ID = 2, Name = "腾讯" });
dataList.Add(new DataModel() { ID = 3, Name = "百度" });
dataList.Add(new DataModel() { ID = 4, Name = "华为" });
AddDataToComboxBox(dataList);
});
}
private void Form2_Load(object sender, EventArgs e)
{
SyncLoadComboxBox();
}
}
public class DataModel
{
public int ID { get; set; }
public string Name { get; set; }
}