C#异步调用、异步回调

1、使用委托的BeginInvoke和EndInvoke实现异步。

public delegate string ShowName();
        static void Main(string[] args)
        {
            ShowName showName = new ShowName(() => { Console.WriteLine("开始起名字"); Thread.Sleep(3000); Console.WriteLine("名字起好了"); return "名字:李磊"; });
            IAsyncResult iAsyncResult = showName.BeginInvoke(null, null);
            Console.WriteLine("等待名字或者干点其他的事情。");
            Console.WriteLine(showName.EndInvoke(iAsyncResult));
            Console.WriteLine("好名字");
            Console.ReadLine();
        }

结果:

上述过程中只有等EndInvoke执行完成后其实就是等着委托执行完成后才会执行Console.WriteLine("好名字");但是Console.WriteLine("等待名字或者干点其他的事情。");是在BeginInvoke之前就执行了。

下面解决因为EndInvoke造成的阻塞,那就是异步回调。在回调里面调用EndInvoke。为什么非要EndInvoke呢一是获取委托的返回值,二据说是防止内存泄漏。

ShowName showName = new ShowName(() => { Console.WriteLine("开始起名字"); Thread.Sleep(3000); Console.WriteLine("名字起好了"); return "名字:李磊"; });
            //做一个回调
            AsyncCallback callBack = new AsyncCallback((IAsyncResult iAsyncResult) =>
            {

                ShowName showNameFun = (ShowName)((AsyncResult)iAsyncResult).AsyncDelegate;
                Console.WriteLine(showNameFun.EndInvoke(iAsyncResult));
                Console.WriteLine("好名字");
            });
            showName.BeginInvoke(callBack, null);
            Console.WriteLine("等待名字或者干点其他的事情。");
            Thread.Sleep(1000);
            Console.WriteLine("名字还没起好?");

调用BeginInvoke之后会继续向下进行不会阻塞,当委托执行完成后会调用回调,在回调中获取了委托的返回值。

结果如下:

2、Task异步

Task<string> task= Task.Run(() => { Console.WriteLine("开始起名字"); Thread.Sleep(3000); Console.WriteLine("名字起好了"); return "名字:李磊"; });
            Console.WriteLine("等待名字或者干点其他的事情。");
            Thread.Sleep(1000);
            Console.WriteLine("名字还没起好?");

结果:

发现一直没有return "名字:李磊";这个返回值。因为没有获取,如果需要获取就需要。

同样的发现task.Result阻塞了线程。和EndInvoke差不多。

3、async和await的异步

 static void Main(string[] args)
        {
            ShowNameAsync();
            Console.WriteLine("等待名字或者干点其他的事情。");
            Thread.Sleep(1000);
            Console.WriteLine("名字还没起好?");
        }


static async Task ShowNameAsync()
        {
            string name = await Task.Run(() => { Console.WriteLine("开始起名字"); Thread.Sleep(3000); Console.WriteLine("名字起好了"); return "名字:李磊"; });
            Console.WriteLine(name);
            return;
        }

结果:

没有阻塞线程,异步方法的返回值据说建议使用Task代替void。还有async和await据说要配对使用。还有异步方法名称最好Async结尾。

最后,配合WPF中的属性绑定会将耗时数据加载呈现出不错的用户体验。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值