异步进阶

一:异步的回调

首先定义一个有参有返回值的委托,实例化并且异步调用

查看BeginInvoke()的参数,第二个类型为AsyncCallback的参数就是启用回调的参数了,F12发现这个参数本身也是一个有参无返回值的委托。

既然他也是一个委托,那也是需要实例化来调用

得到如下代码

  private void button3_Click_1(object sender, EventArgs e)
        {
            Console.WriteLine("***********************************异步开始***********************************");
            rtfunction rt = new rtfunction(lodinglong);

            AsyncCallback callback = new AsyncCallback(back);
            IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步", callback, null);

            Console.WriteLine("***********************************异步结束***********************************");

        }

        public void back(IAsyncResult ar)
        {
            Console.WriteLine("执行回调");
        }

        private static long lodinglong(string name, string project)
        {
            Console.WriteLine("这里是{0}开始执行{1},这里是线程{2}", name, project, Thread.CurrentThread.ManagedThreadId); ;
            long result = 0;
            for (int i = 0; i < 1000000; i++)
            {
                result += i;
            }
            Thread.Sleep(2000);//等待2s
            Console.WriteLine("这里是{0}结束执行,这里是线程{1},计算结果为{2}", name, Thread.CurrentThread.ManagedThreadId, result); ;
            return result;
        }

得到的结果如下:可以看出,回调方法是在异步完成之后进行的

二:异步的状态参数

看完了回调,再接着看最后一个参数 obiect。此参数在回调中使用

上一步说到AsyncCallback其实也是一个委托,其中它还有一个类型为IAsyncResult的参数,这个参数就是我们的obiect。F12进去查看IAsyncResult,可以看到以下几种方法,其中AsyncState就是状态参数

在方法里面加入我们的第四个参数并且运行程序,代码如下

       private void button3_Click_1(object sender, EventArgs e)
        {
            Console.WriteLine("***********************************异步开始***********************************");
            rtfunction rt = new rtfunction(lodinglong);

            AsyncCallback callback = new AsyncCallback(back);
            IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步", callback, "用于回调的");
            //lambda写法
            //IAsyncResult AsyncResults = rt.BeginInvoke("异步", "异步",
            //  t => Console.WriteLine("执行回调,状态是{0}", t.AsyncState),
            //    "用于回调的");

            Console.WriteLine("***********************************异步结束***********************************");

        }

        public void back(IAsyncResult ar)
        {
            Console.WriteLine("***********************************这里是回调的开始***********************************");
            Console.WriteLine("执行回调,状态是{0}", ar.AsyncState);
            Console.WriteLine("***********************************这里是回调的结束***********************************");

        }

        private static long lodinglong(string name, string project)
        {
            Console.WriteLine("这里是{0}开始执行{1},这里是线程{2}", name, project, Thread.CurrentThread.ManagedThreadId); ;
            long result = 0;
            for (int i = 0; i < 1000000; i++)
            {
                result += i;
            }
            Thread.Sleep(2000);//等待2s
            Console.WriteLine("这里是{0}结束执行,这里是线程{1},计算结果为{2}", name, Thread.CurrentThread.ManagedThreadId, result); ;
            return result;
        }

结果如下

三.异步的返回值

1.使用EndInvoke会卡住当前线程

       private void button3_Click_1(object sender, EventArgs e)
        {
            Console.WriteLine("***********************************异步开始***********************************");
            rtfunction rt = new rtfunction(lodinglong);

            AsyncCallback callback = new AsyncCallback(back);
            //lambda
            //IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步",
            //  t =>  Console.WriteLine("执行回调,状态是{0}", t.AsyncState),
            //    "用于回调的");
            IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步", callback, "用于回调的");
            var result = rt.EndInvoke(AsyncResult);//等待异步结束,卡主当前线程
            Console.WriteLine("返回的结果是{0}", result);

            Console.WriteLine("***********************************异步结束***********************************");

        }

        public void back(IAsyncResult ar)
        {
            Console.WriteLine("***********************************这里是回调的开始***********************************");
            Console.WriteLine("执行回调,状态是{0}", ar.AsyncState);
            Console.WriteLine("***********************************这里是回调的结束***********************************");

        }

        private static long lodinglong(string name, string project)
        {
            Console.WriteLine("这里是{0}开始执行{1},这里是线程{2}", name, project, Thread.CurrentThread.ManagedThreadId); ;
            long result = 0;
            for (int i = 0; i < 1000000; i++)
            {
                result += i;
            }
            Thread.Sleep(2000);//等待2s
            Console.WriteLine("这里是{0}结束执行,这里是线程{1},计算结果为{2}", name, Thread.CurrentThread.ManagedThreadId, result); ;
            return result;
        }

划重点!!到这里会发现,程序这时候真正按照我想要的顺序在进行。等待异步完成,异步结束,获取返回值,进行回调。

2.可在回调中使用

   //lambda
            IAsyncResult AsyncResult = rt.BeginInvoke("异步", "异步",
                t =>
                {
                    Console.WriteLine("***********************************这里是回调的开始***********************************");
                    Console.WriteLine("执行回调,状态是{0}", t.AsyncState);
                    var result = rt.EndInvoke(t);
                    Console.WriteLine("返回的结果是{0}", result);
                    Console.WriteLine("***********************************这里是回调的结束***********************************");

                },
                "用于回调的");

3.AsyncResult.IsCompleted可用于判断异步是否执行完成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值