多线程委托之跨线程问题分析--在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke(解决方法已更新)

时间:2022-08-27 21:46:57

多线程委托之跨线程问题分析

今天在写一个程序测试运行跨线程同步的时候出一个异常信息。

异常信息:System.InvalidOperationException

在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”

这程序目前发现这异常出错原因:

可能是一个方法无法调用一个对象的一个方法且该对象的状态无法支持该方法调用,则引发了此异常。通过

进行判断句柄是否创建,由于其他原因没有创建或者已经释放了。目前解决判断只用到“this.IsHandleCreated || IsDisposed”,目前没完全弄懂这个异常具体产生的原因。我在另加一个控件去处理主窗体显示程序,则运行正常。从 UI 线程进行 UI 更新引发 InvalidOperationException | 避免在非 UI 线程上引发 InvalidOperationException

大多数 .NET GUI(图形用户界面)应用框架(如 Windows 窗体和 Windows Presentation Foundation (WPF))只允许从创建和管理 UI 的线程(主线程或 UI 线程)访问 GUI 对象。则尝试从非 UI 线程访问 UI 元素时,将引发 InvalidOperationException。





<pre name="code" class="java">if (this.IsHandleCreated || IsDisposed)
this.Invoke(F2A.xianshi, new object[] { j1, j2, j3, j4 });
else
return;


 
</pre><pre name="code" class="java">#region 主窗体手动刷新程序
private void button1_Click(object sender, EventArgs e)
{
setForm2 setf2 = new setForm2();
Form2A F2A = new Form2A();
if (Form2A.Text1 != null)
{
Thread thread = new Thread(new ThreadStart(delegate
{
string j1 = "",j2 = "",j3 = "",j4 = "";
F2A.xianshi = new delexianshi(label);//委托实例化
string[] str = setf2.Xianshi().ToArray();//输入窗体数据处理后,List转换成数组
for (int i = 0; i < str.Length; i++)
{
if (i == 0) { j1 = str[i]; }
else if (i == 1) { j2 = str[i]; }
else if (i == 2) { j3 = str[i]; }
else { j4 = str[i]; }
}
if (this.IsHandleCreated || IsDisposed)
this.Invoke(F2A.xianshi, new object[] { j1,j2,j3,j4 });
else
return;
}));
thread.IsBackground = true;
thread.Start();
}
}
#region 主窗体label刷新
public void label(string val1, string val2, string val3, string val4)
{
getshuju1.Text = val1;
getlabel2.Text = val2;
getlabel3.Text = val3;
getlabel4.Text = val4;
}

#region 数据处理程序
public List<string> Xianshi()
{
string[] f2 = new string[4] { Form2A.Text1.ToString(), Form2A.Text2.ToString(),
Form2A.Text3.ToString(), Form2A.Text4.ToString() };
List<string> list = new List<string>();
for (int i = 0; i < f2.Length; i++)
{
list.Add("01" + " " + f2[i]);
}
return list;
}

</pre><pre name="code" class="csharp"><pre name="code" class="java">#region 输入赋值
private void button1_Click(object sender, EventArgs e)
{
Text1 = settextBox1.Text;
Text2 = settextBox2.Text;
Text3 = settextBox3.Text;
Text4 = settextBox4.Text;
this.Close();
}


 

跨线程异常(同步,异步)

异常:线程间操作无效: 从不是创建控件“xxx”的线程访问它。

解决方法:this.Inovke(指定委托,委托指定方法的参数值)


解决此异常方法:本博客中的《两个Form窗体之间的关联性问题<跨窗体数据同步>》