C#实现窗体与子线程的交互的方法
本文实例简述了C#实现窗体与子线程间通讯的方法,对于C#初学者有一定的借鉴价值。具体方法如下: 一般来说窗体上的UI在默认情况下不允许使用子线程(或者其它非创建控件的UI线程)去控制(这在NET2.0以下是允许的,但是考虑到安全性等问题,从2.0开始就禁止使用这个功能,除非Form的CheckForIllegalCrossThreadCalls=true,不推荐这样使用)。 那么如何实现C#窗体与子线程的交互呢?具体方法如下: 一、使用Invoke或者BeginInvoke方法: 用一个线程,里边调用Invoke或者BeginInvoke方法即可: public partial class Form1 : Form { public void Processing(int num) { int answer = 2; Task t = new Task(() => { for (int i = 3; i <= num; i++) { answer *= i; } this.BeginInvoke(new MethodInvoker(() => { Thread.Sleep(3000); MessageBox.Show("Finished!") })); MessageBox.Show("OK"); }); t.Start(); } public Form1() { InitializeComponent(); } private void button1_Click(object sender,EventArgs e) { MessageBox.Show("First!"); Processing(10); } } 这里值得注意: 二、线程同步SynchronizedContext: public partial class Form1 : Form { public void Processing(int num,SynchronizationContext context) { int answer = 2; Task t = new Task(() => { for (int i = 3; i <= num; i++) { answer *= i; } SynchronizationContext.SetSynchronizationContext(context); SynchronizationContext.Current.Post((obj) => { Thread.Sleep(3000); MessageBox.Show("Finished"); },null); MessageBox.Show("Last"); }); t.Start(); } public Form1() { InitializeComponent(); } private void button1_Click(object sender,EventArgs e) { MessageBox.Show("First!"); Processing(10,SynchronizationContext.Current); } } 和BeginInvoke、Invoke类似,需要注意: 大家如果仔细实验代码,还会发现无论何种情况,弹出“Finished”框框总是界面“假死”3秒,是的,证明了以上4个方法都是在UI线程上执行的(只不过是同步或者异步向窗体消息泵发送信息而已)。所以应该“一次性地把数据在子线程中先全部处理干净(在Invoke,BeginInvoke,Send或者Post前得出结果,写代码),然后一次性发送通知给窗体,更新界面即可)。 此外还需要注意: 任何委托(Delegate)也有BeginInvoke方法,它是真正的异步,一旦Invoke一定是开辟一个线程去执行的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |