异步中的跨线程赋值问题

最近写一些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;
        }
    }
}

posted @ 2010-12-09 01:45  TerryZou1989  阅读(632)  评论(2编辑  收藏  举报