异步委托

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步委托相关的知识,希望对你有一定的参考价值。

委托实现多窗体传值

主窗体的代码:

  public partial class FrmMain : Form
    {
        //[3] 创建委托对象(委托对象能够将委托和具体方法关联) 
        public ShowCounterDelegate msgSender;


        public FrmMain()
        {
            InitializeComponent();
            //创建从窗体对象
            FrmOther01 objFrm01 = new FrmOther01();
            FrmOther02 objFrm02 = new FrmOther02();
            FrmOther03 objFrm03 = new FrmOther03();

            //4.将委托变量和具体方法关联
            this.msgSender += objFrm01.Receiver;
            this.msgSender += objFrm02.Receiver;
            this.msgSender += objFrm03.Receiver;

            //显示三个从窗体
            objFrm01.Show();
            objFrm02.Show();
            objFrm03.Show();
        }
        private int counter = 0;
        /// <summary>
        /// 发消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClick_Click(object sender, EventArgs e)
        {
            counter++;
            //msgSender(counter.ToString()); //5.调用委托变量传递信息
            msgSender.Invoke(counter.ToString());
        }
        /// <summary>
        /// 复位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReset_Click(object sender, EventArgs e)
        {
            counter = 0;
            msgSender("0");
        }
    }

    //1.声明委托
    public delegate void ShowCounterDelegate(string counter);

 子窗体的代码:

  //2.根据委托定义方法(接收委托传递的信息)
        public void Receiver(string counter)
        {
            this.IblCounter.Text = counter;
        }
 //2.根据委托定义方法(接收委托传递的信息)
        public void Receiver(string counter)
        {
            this.IblCounter.Text = counter;
        }
  //2.根据委托定义方法(接收委托传递的信息)
        public void Receiver(string counter)
        {
            this.IblCounter.Text = counter;
        }

 同步委托和异步委托

 public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }


        private void btnExe1_Click(object sender, EventArgs e)
        {
            this.lblCount1.Text = ExectueTask1(10).ToString();
            this.lblCount2.Text = ExectueTask2(10).ToString();
        }



        //2.根据委托定义实现的方法
        private int ExectueTask1(int num)
        {
            System.Threading.Thread.Sleep(5000);//延迟5秒
            return num * num;
        }

        private int ExectueTask2(int num)
        {
            return num * num;
        }
        private void btnExe2_Click(object sender, EventArgs e)
        {
            MyCalculator objMyCal = ExectueTask1; //创建委托变量,代表方法1

            //通过委托异步调用方法
            //委托类型的 BeginInvoke(<输入和输出参数>,AsyncCallback callback,object asyncState)方法:异步调用的核心
            //第一个方法10,表示委托对应的实参
            //第二个参数callback:回调函数,表示异步调用后自动调用的函数
            //第三个参数asyncState,用于向回调函数提供参数信息
            //返回值 IAsyncResult-->异步操作状态接口,封住了异步执行的参数


            //异步调用任务
            IAsyncResult result = objMyCal.BeginInvoke(10,null,null);
            this.lblCount1.Text = "正在计算请稍等。。。";


            //同步执行其他任务
            this.lblCount2.Text = ExectueTask2(10).ToString();

            //获取异步执行的结果
            int res = objMyCal.EndInvoke(result);
            //委托类型的EndInvoke() 方法:借助于IAsyncResult接口对象,不断的查询异步调用是否结束
            //该方法知道异步调用的方法所有参数,所以,异步调用完毕后,取出异步调用的结果作为返回值
            this.lblCount1.Text = res.ToString();
        }
       

        //1.定义一个委托
        public delegate int MyCalculator(int num);
    }

 异步委托:

 public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
            //初始化委托变量
            this.objMyCal = new MyCalculator(ExecuteTask);

            //Lambda表达式
            //this.objMyCal = (num, ms) =>
            //    {
            //        System.Threading.Thread.Sleep(ms);
            //        return num * num;
            //    };
        }
        //1.声明一个委托  延迟的秒数
        public delegate int MyCalculator(int num, int ms); //延迟的秒数

        //2.根据委托定义方法:返回一个数的平方
        private int ExecuteTask(int num, int ms)
        {
            System.Threading.Thread.Sleep(ms);
            return num * num;
        }

        //3.创建委托变量
        MyCalculator objMyCal = null;


        //同时执行多个任务
        private void btnExec_Click(object sender, EventArgs e)
        {
           
            //产生10个任务
            for (int i = 1; i < 11; i++)
            {
                //开始异步执行,并封装异步函数
                objMyCal.BeginInvoke(10 * i, 1000 * i, MyCallBack, i);
                //最后一个参数i给回调函数AsyncState赋值,这个字段是object类型,如果数据很多,可以传递集合或者类和结构
            }
        }

        //5.编写回调函数
        private void MyCallBack(IAsyncResult result)
        {
          int res=  objMyCal.EndInvoke(result);
            
            //异步显示结果形式:第一个的计算结果:100
          Console.WriteLine("第{0}个计算结果:{1}",result.AsyncState.ToString(),res);
        }
        //异步编程总结
        //1.异步编程是建立在委托基础上的编程方法
        //2.异步调用的每个方法都是在独立的线程上执行的。因此,本质上就是一种多线程程序,也可以说是一个“简化的多线程技术”
        //3.比较适合在后台运行较为耗时间的《简单任务》,并且要求任务之间是独立的,任务中不要有直接访问可视化控件的内容。
        //4.如果后台任务要求必须按照特定顺序执行,或者访问到特定的共享资源,异步编程不太适合,而应该选择多线程开发技术   
    }

 

以上是关于异步委托的主要内容,如果未能解决你的问题,请参考以下文章

异步委托

C# Winform 多线程异步委托进度条

.Net 异步委托中止

C#委托异步调用

您如何实现异步操作委托方法?

如何将异步Func或Action转换为委托并调用它