异步委托

当同步调用委托时,Invoke()方法直接对当前线程调用目标方法;

当异步调用委托时,CLR将对请求进行排队并立即返回到调用方,将对来自线程池的线程调用该目标方法,提交请求的原始线程继续与目标方法并行执行,该目标方法是对线程池线程运行的.

1)、BeginInvoke()方法

BeginInvoke()方法启动异步调用,它与需要异步执行的方法具有相同的参数。

另外,还有两个可选参数:第一个参数是AsyncCallback委托,该委托引用在异步调用完成时要调用的方法;第二个参数是用户定义的对象,该对象可向回调方法传递信息;

BeginInvoke立即返回,不等待异步调用完成;

BeginInvoke返回IAsyncResult,这个结果可用于监视异步调用的进度;

2)、EndInvoke()方法

EndInvoke()方法检索异步调用的结果;

在调用BeginInvoke()方法后,可以随时调用EndInvoke()方法,如果异步调用尚未完成,则EndInvoke()方法将一直阻止调用线程,直到异步调用完成后才允许调用线程执行;

EndInvoke()的参数需要异步执行的方法的out和ref参数以及由BeginInvoke()返回的IAsyncResult。

代码一,同步执行:
        delegate int MyDel(int a, int b);
        static void Main(string[] args)
        {
            MyDel del = new MyDel(AddFun);
            del.Invoke(2, 2);

            while (true)         //主线程一直工作
            {
                Console.WriteLine("主线程{0}在工作", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(1000);
            }
        }

        static int AddFun(int a, int b)
        {
            Console.WriteLine("工作线程{0}在跑着,值为{1}", Thread.CurrentThread.ManagedThreadId, a + b);
            Thread.Sleep(5000);    //这里我们让线程睡眠5秒,看主线程是否被阻塞
            return a + b;
        }

结果:


这里停顿了5秒之后...


上面证明了这个委托会阻塞主线程...

那么如何不让它阻塞呢!想到了多线程,

但是Thread里面的委托  参数ThreadStart和ParameterThreadStart中的委托都没有返回值类型(void)

那么我们就引入主题,异步委托---


//AsyncCallBack为回调函数,委托执行完以后让回调函数去处理结果,这样就不会阻塞主线程了。

    实际也就是委托调执行以后,又一个委托把结果进行处理

        delegate int MyDel(int a, int b);
        static void Main(string[] args)
        {
            MyDel del = new MyDel(AddFun);
            //del.Invoke(2, 2);


            del.BeginInvoke(1, 2, new AsyncCallback(AscCallBack), null);


            while (true)
            {
                Console.WriteLine("主线程{0}在工作", Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(1000);
            }
        }


        static int AddFun(int a, int b)
        {
            Console.WriteLine("工作线程{0}在跑着,值为{1}", Thread.CurrentThread.ManagedThreadId, a + b);
            Thread.Sleep(5000);
            return a + b;
        }
        static void AscCallBack(IAsyncResult result)
        {
            AsyncResult aResult = (AsyncResult)result;
            MyDel del = (MyDel)aResult.AsyncDelegate;
            int addResult = del.EndInvoke(result);
            Console.WriteLine("我是主线程还是子线程?噢原来是{0}", Thread.CurrentThread.ManagedThreadId);
        }

执行结果:


到5秒的时候


我们可以看到,主线程没有被阻塞,而且工作线程和主线程不是同一个线程。

其实异步委托是在线程池内获取到一个线程,也是一种多线程的体现。

那么什么时候用多线程,什么时候用异步委托呢?  上面说过多线程的委托没有返回值,而异步委托可以自己随便定义。


当需要执行I/O操作时,使用异步操作比使用线程+同步I/O操作更合适。I/O操作不仅包括了直接的文件、网络的读写,还包括数据库操作、Web Service、HttpRequest以及.Net Remoting等跨进程的调用。
  而线程的适用范围则是那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行。但是往往由于使用线程编程的简单和符合习惯,所以很多朋友往往会使用线程来执行耗时较长的I/O操作。这样在只有少数几个并发操作的时候还无伤大雅,如果需要处理大量的并发操作时就不合适了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值