前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C#同步方法转异步 创建新线程AMP 转 EAP

C#同步方法转异步 创建新线程AMP 转 EAP

作者头像
林德熙
发布2018-09-18 17:20:21
6580
发布2018-09-18 17:20:21
举报
文章被收录于专栏:林德熙的博客林德熙的博客

本文来告诉大家如何把同步的代码转换为异步

创建新线程

最简单的方法是创建一个新的线程,创建的方法是使用 Task.Run ,请看下面代码,原来有一个函数 Delay 需要把他转换为异步,就可以使用 DelayAsync 里面用一个线程

代码语言:javascript
复制
  public async Task DelayAsync()
  {
  
      await Task.Run(()=>Delay());
  }

  private void Delay()
  {


  }

AMP 转 EAP

在很古老的开发,微软告诉大家使用 AMP 异步编程模型 Asynchronous Programming Model,这个模型就是使用 Begin xx 和 End xx 的方法 如 FileStream.BeginRead 和Stream.EndRead 表示

现在微软告诉大家,建议使用 EAP 基于事件的异步模式,也就是 Async 的模型

例如有一个文件读取,文件读取可以使用 BeginRead 和 EndRead ,看到下面代码大家就会觉得这很难用

代码语言:javascript
复制
            var fileStream = new FileStream("E:\\lindexi\\博客",FileMode.Open);

            var buffer =new byte[65535];
            IAsyncResult asyncResult=null;
            fileStream.BeginRead(buffer, 0, buffer.Length, ar => { asyncResult = ar;}, null);

            fileStream.EndRead(asyncResult);

好在微软提供一个方式把上面的代码转换为 async ,方法是 Task.Factory.FromAsync 请看代码

代码语言:javascript
复制
await Task.Factory.FromAsync(fileStream.BeginRead, fileStream.EndRead, buffer, 0, buffer.Length, null);

如果希望对于如动画的等待,那么建议看如何实现一个可以用 await 异步等待的 Awaiter - walterlv

如何实现一个可以用 await 异步等待的 Awaiter - walterlv复制出来类 DispatcherAsyncOperation

动画的等待是在动画结束返回函数,也许这里比较难说,动画有开始和结束事件,希望在结束事件函数才返回

代码语言:javascript
复制
       private void TrirlelJallardra()
        {
            // 执行动画
            TeedraiseTeretal();

            // 期望在动画结束才做的代码

        }

        /// <summary>
        /// 执行动画
        /// </summary>
        private void TeedraiseTeretal()
        {
            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回
            };
        }

因为 TrirlelJallardra 拿不到 storyboard.Completed 所以如果要在动画完成之后写调用代码是很难的。

为什么需要在其他函数写?如果是继续执行动画,而且需要在上一个动画执行完成,写在 Completed 的代码会很多。如果可以使用下面的函数的方法,可读性比较好

代码语言:javascript
复制
      private void TrirlelJallardra()
        {
            // 执行动画
            Animation1();

            // 期望在动画1完成继续动画2
            Animation2();

            // 在上一个动画完成才调用下一个动画

            Animation3();

        }

        /// <summary>
        /// 执行动画1
        /// </summary>
        private void Animation1()
        {
            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回
            };
        }

        /// <summary>
        /// 执行动画2
        /// </summary>
        private void Animation2()
        {
            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回
            };
        }

        /// <summary>
        /// 执行动画3
        /// </summary>
        private void Animation3()
        {
            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回
            };
        }

如果需要写在回调里,那么可读性比较差

代码语言:javascript
复制
     private void TrirlelJallardra()
        {
            // 执行动画
            Animation1();
        }

        /// <summary>
        /// 执行动画1
        /// </summary>
        private void Animation1()
        {
            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回

                // 期望在动画1完成继续动画2
                Animation2();

            };
        }

        /// <summary>
        /// 执行动画2
        /// </summary>
        private void Animation2()
        {
            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回


                // 在上一个动画完成才调用下一个动画

                Animation3();
            };
        }

        /// <summary>
        /// 执行动画3
        /// </summary>
        private void Animation3()
        {
            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回
            };
        }

那么这时使用 DispatcherAsyncOperation 就可以做异步,让代码可读性比上面好

代码语言:javascript
复制
     private async void TrirlelJallardraAsync()
        {
            // 执行动画
            await Animation1();

            // 期望在动画1完成继续动画2
            await Animation2();

            // 在上一个动画完成才调用下一个动画

            await Animation3();
        }

        /// <summary>
        /// 执行动画1
        /// </summary>
        private DispatcherAsyncOperation<bool> Animation1()
        {
            var dispatcherAsyncOperation = DispatcherAsyncOperation<bool>.Create(out var action);

            var storyboard = new Storyboard();

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) =>
            {
                // 这时函数才返回
                action(true, null);
            };

            return dispatcherAsyncOperation;
        }

        /// <summary>
        /// 执行动画2
        /// </summary>
        private DispatcherAsyncOperation<bool> Animation2()
        {
            var storyboard = new Storyboard();

            var dispatcherAsyncOperation = DispatcherAsyncOperation<bool>.Create(out var action);

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) => { action(true, null); };

            return dispatcherAsyncOperation;
        }

        /// <summary>
        /// 执行动画3
        /// </summary>
        private DispatcherAsyncOperation<bool> Animation3()
        {
            var storyboard = new Storyboard();

            var dispatcherAsyncOperation = DispatcherAsyncOperation<bool>.Create(out var action);

            //设置动画

            storyboard.Begin(this);

            storyboard.Completed += (sender, args) => { action(true, null); };

            return dispatcherAsyncOperation;
        }

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 创建新线程
  • AMP 转 EAP
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档