多线程

多线程编程中,常在工作线程中去更新界面显示,在多线程中直接调用界面控件的方法是错误的做法,因为不能跨线程调用控件(VS默认不允许),所以Invoke和BeginInvoke就解决了这个问题,是多线程中安全的更新界面显示。

虽然VS默认不允许跨线程调用控件,但是可以手动关闭此项检查:在窗体加载的时候将对控件的检查给置为false  即:Control.CheckForIllegalCrossThreadCalls = false;;

在多线程编程时,将工作线程中涉及更新界面的代码封装为一个方法,通过invoke或者BeginInvoke去调用,两个的区别就是一个导致工作线程等待,而另一个则不会。

“一面响应操作,一面添加节点”只是相对的,使UI线程的负担不至于太大,因为界面的正确更新始终要通过UI线程去做,我们要做的就是在工作线程中包揽大部分的运算,将对纯粹的界面更新放到UI线程中,这样
减轻UI线程的负担。

/*Invoke与BeginInvoke方法的区别:

*
*  Invoke:在拥有此控件的基础窗口句柄的线程上执行指定的委托 同步
*  BeginInvoke:在创建控件的基础窗口句柄所在的线程上 异步执行 指定的委托
*
*  Invoke和BeginInvoke所提交的委托方法都是在主线程上执行的。
*  Invoke会将提交的委托方法执行完后,才继续往下执行
*  BeginInvoke则将提交完委托方法后,子线程继续执行,不会一直等待委托方法的完成
*/

一般使用多线程时都会考虑同步执行还是异步执行,并且用到委托

同步执行:在主线程执行时,主线程调用一个其他方法,此时主线程阻塞,等待调用的方法执行完成后主线程才能继续执行。
异步执行:在主线程执行时,打开一个子线程,主线程继续执行,当主线程需要子线程运行的结果时,主线程直接调用子线程运行的结果,如果在调用的时候
                  子线程还没有执行完成,主线程等待,直到子线程执行完成,主线程再继续执行。

异步回调:主线程执行时,打开一个子线程,主线程与子线程同步执行,主线程需要子线程运行的结果则调用其结果

委托:实际上就是将封装的方法当做一个参数传递给线程

/*示例

*1、工作线程:窗体加载

*2、子线程:界面text控件完成更新,即给text控件赋值

*运行逻辑:

*主线程开始工作,开启子线程,实例化委托,Invoke提交委托方法执行,然后主线程继续执行

*

*/

private delegate void a(); //定义 一个委托

private a b; //声明委托

Thread thread; //线程

private void Form_Load(object sender, EventArgs e)

{

  b = new a(d); //实例化委托

  thread = new Thread(c);  //实例化线程

  thread.Start(); //开启子线程,调用回调函数

}

///回调函数

private void c()

{

   textBox1.Invoke(b); //子线程同步执行

}

private void b()

{

  textBox1.Text = "123";

}

原文地址:https://www.cnblogs.com/Java-125/p/12857403.html