异步中的跨线程赋值问题
最近写一些C/S架构的项目,总是用到多线程和异步处理数据,这样可以防止我的WinForm程序出现假死状态,但是有一点,在子线程中得到的数据,我如何放到我的主线程的控件上显示呢,这就出现了跨线程赋值的问题,开始我们很简单的可以用“CheckForIllegalCrossThreadCalls = false;”很容易解决,但是,这是很不安全的,这样的话,任何子线程都可以改变UI上面的值,如果有两个或两个以上的子线程同时要给同一个UI上的同一个控件赋值,那样我们就会只看到一个值,这个只是不是我们想要的就不一定了,而Invoke会由我们控制,不会出现刚刚那种情况,如果出现,你是写代码的逻辑不够清楚,不多说了,以下是我的Demo,有注释,自认为很清楚,供大家参考,如果有什么问题可以提出来,毕竟我理解的不是很深刻嘛!谢谢
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace deleAsny
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//CheckForIllegalCrossThreadCalls = false;//如果我们不用Controls.Invole()进行跨线程赋值,我们就在构造函数中用这句话,但只这句话很不安全,所以万不得已,慎用这句话
}
public delegate int MathDel(int a, int b);// 定义一个委托 为后面的异步加法运算做准备
public delegate void ResultDel(int re);//定义一个委托,为后面跨线程赋值做准备
private void btn_Add_Click(object sender, EventArgs e)
{
if (this.txtOne.Text.Trim() != "" && this.txtTwo.Text.Trim() != "")
{
Math mc=new Math();//实例一个自定义数学类,里面有一个Add方法
int one = Convert.ToInt32(this.txtOne.Text.Trim());//得到需要计算的第一个数值,并转换成整型
int two = Convert.ToInt32(this.txtTwo.Text.Trim());//得到需要计算的第二个数值,并转换成整型
MathDel m1 = new MathDel(mc.Add);//实例一个委托,并创建一步的子线程
m1.BeginInvoke(one, two, new AsyncCallback(MyAdd), m1);
//回调自己的子线程地方法MyAdd
}
}
void MyAdd(IAsyncResult result)
{
MathDel m2= result.AsyncState as MathDel;//从一步操作的状态中获取用户定义的对象,并赋给m2,他是一个委托类型的
int re = m2.EndInvoke(result);//断开主线程控制端口,并获取异步中的到的结果
ResultDel r=new ResultDel(Result);//实例一个跨线程赋值的委托,并传进Result
txtResult.Invoke(r,re);//用Controls.Invoke()进行异步跨线程赋值,re是计算的结果,同时在这里是r中Result方法的参数
}
void Result(int re)
{
txtResult.Text = re.ToString();//终于我们可以把得到的结果赋给我们的一个控件的Text
}
}
public class Math
{
public int Add(int a, int b)
{
Thread.Sleep(10000);//让此方法睡10秒钟,模拟复杂与运算的时间
return a + b;
}
}
}