0

0

C# 5.0功能之Async一瞥的图文代码详解

黄舟

黄舟

发布时间:2017-03-03 13:30:23

|

1618人浏览过

|

来源于php中文网

原创

距离微软发布async ctp已经有个把月了吧,周围大家都在热议着async。如果你对async已经非常熟悉,那么,请直接略过……如果你跟我一样,只会一点点异步编程,但又觉得以前的异步编程比较麻烦,那么,让我们一起来探索一下下一代的c#会给我们带来什么。(async ctp同样对vb有支持的。)


本文的例子基于Async CTP SP1 Refresh完成。由于 Async还处于CTP阶段,很多东西还在讨论,因此,也许待到C# 5.0发布的时候,细节还会变动。但是,大体的思路,概念应该是不会有什么变化了。

 

进入正题:

首先,要试用Async功能,我们需要安装Visual Studio 2010 SP1Microsoft Visual Studio Async CTP (SP1 Refresh)

 

我们首先设定一个简单的任务,分别来看一下,同步编程,利用回调进步异步编程和Async编程的方法,然后来通过他们来分析一下,Async到底是什么,它给我们带来了什么。

 

任务:

建立一个Windows Form应用程序,当点击按钮时,先显示一行字,例如,开始计算什么的,用以表示状态,然后计算从1int.Max/2的累加,并把结果显示出来。

 

同步我们会这么做:

首先,写一个函数来实现基本算法:

@@######@@


广研企业网站管理系统中英文双语版
广研企业网站管理系统中英文双语版

v1.8新增功能简介: 一、后台新增生成网站地图和生成Sitemap.xml的功能。 二、新增下载中心功能,可在后台上传doc,xls,ppt,rar,pdf文件。 三、新增产品缩略图自动缩放功能,图片按比例缩放,解决了图片变形问题。 四、新闻、产品详细页新增了上一个、下一个的功能,改善用户体验。 五、在线客服新增了阿里巴巴贸易通在线客服。 六、可在后台设置分享代码,如百度分享和AddThis等。

下载

然后,添加一个按钮的Click事件处理程序:

@@######@@


代码第一行改写Label的字样;第二行调用算法获得结果;第三行把结果输出。看似挺不算的。运行一下,就会发现有两个问题:

  1. 这个算法需要四五秒钟左右的实现时间,并且在这几秒钟的时间里,界面是锁死的,也就是说应用程序就像死了一样,它不接受任何用户操作。(也许我的电脑比较差,呵呵,所以,如果你没有遇到这种情况,请加大输入参数的值,让它算一会儿。)

  1. 我们没有看到Start to do something这一行字。

 

OK,出现这个现象也是可以理解的,因为我们把大量的运算添加到了UI线程里面了。所以,解决方法就是把它放到外面。我试了一下不用Async,实现的代码如下:

@@######@@


如果你觉得这段代码比较晕,那就跳过这一节吧。可能我代码写得不好,大家将就看我简单解释一下,我首先给DoSomething写了一个代理,然后,调用了代理的BeginInvoke方法,把算法放到了其它的Thread中去调用了。这个代理执行完了以后,因为它不会直接返回一个long型的值,而是会去执行一个AsyncCallBack,所以,就在这个Callback里,去调用这个代理的EndInvoke()

 

好吧,且不论代码质量,这个就是有Async之前的一种实现异步的方法。

从这个代码里,我们完全看不到原来代码的影子,我也没有办法像解释同步代码一样解释:第一、第二、第三……有了Async之后呢?呵呵,代码说明一切:

@@######@@


三件事:

第一:添加文件引用:AsyncCtpLibrary.dll。相信Async正式发布之后,这个会出现在.NET应用程序集里。

第二:把DoSomething封装成一个Task

第三:添加一些关键字,例如async,例如await

 

我们来仔细看一下代码:

首先,我把要异步执行的代码的返回值写成Task。这个返回值其实有三个选项:voidTaskTask,具体怎么用,大家查MSDNC#4.0中的Task类吧。

然后,我调用了TaskEx中的Run方法,传递给它一个返回值为long的方法——就是我们的任务的算法啦。

如果你有兴趣研究,可以看一下Run其实调用了Task.Factory.StartNew,而这个Start则是先建了一个Task,然后调用了它的Start方法……

好,把算法封成任务部分完成。

 

第二部分代码比较容易解释了:

第一行改写Label的字样;第二行调用算法获得结果;第三行把结果输出。本行复制/粘贴自前文:-)

 

呵呵,让我们看看细一点,比较一下SyncAsync的代码:

Sync

Async

        private void btnSync_Click(object sender, EventArgs e)
                    {
                        lblResult.Text = 
"Start to do something . . .";
                        
long value = DoSomething(int.MaxValue / 2);
                        lblResult.Text = value.ToString();
                    }

        private async void btnAsync_Click(object sender, EventArgs e)
                    {
                        lblResult.Text = 
"Start do something...";
                        
var x = await DoSomethingAsync(int.MaxValue / 2);
                        lblResult.Text = x.ToString();
                    }

首先,我们在方法名上加上async修饰,声明这是一个有异步调用的方法;

然后,我们在返回Task的函数调用(DoSomethingAsync)之前添加一个await关键字。来猜猜看x是什么类型的?答案是long型。有了await之后,即使在设计时,编译器会自动把Task的类型,转换成T类型。

 

代码到这里结束了,但是,新的Async功能给我们带来了什么?是异步编程的能力吗?我们用Callback同样可以实现异步,而IAsyncCallback接口应该在.NET 1.1中已经实现了;多线程的命名空间也早就存在;TaskC# 4.0中被引入……

 

我想,Async给程序员带来的是一种代码逻辑为中心并且实现多线程编程的方式。通过最后的比较,我们看到,Async的代码与Sync的代码相差无几,程序不再需要花大量精力去考虑回调、同步等等的问题……这与C#一直在努力的方向是一致的,程序员更多的来描述是什么而不是怎么做。

 

最后,附上应用程序下载和源代码,还有运行界面截图……(好吧,我不是美工,请原谅 :-)

点击下载源代码

 

点击Async,看到运行提示:

显示执行结果:

最新最官方的Async资料在这儿:^v^

 http://msdn.microsoft.com/Async

 以上就是C# 5.0功能之Async一瞥的图文代码详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!

  #region
 Do things

                     
public
 
long
 DoSomething(
int
 n)

                     {

                         
long
 result = 1;

                         
for
 (
int
 i = 1; i <= n; i++)

                         {

                             result += i;

                         }

                         
return
 result;

                     }
        #endregion
 
private
 
void
 btnSync_Click(
object
 sender, 
EventArgs
 e)

                     {

                         lblResult.Text = 
"Start to do something . . ."
;

                         
long
 value = DoSomething(
int
.MaxValue / 2);

                         lblResult.Text = value.ToString();

                     }
private
 
void
 btnCallback_Click(
object
 sender, 
EventArgs
 e)

                     {

                         lblResult.Text = 
"Start to do something . . ."
;

                         Func<
int
, 
long
> callBackDelegate = 
this
.DoSomething;
            callBackDelegate.BeginInvoke(

                             
int
.MaxValue / 2,

                             
new
 AsyncCallback(

                             a =>

                             {

                                 lblResult.Invoke(
new
 MethodInvoker(() =>

                                     {

                                         lblResult.Text = callBackDelegate.EndInvoke(a).ToString();

                                     }));

                             }),

                             
null
);

                     }
public
 
Task
<
long
> DoSomethingAsync(
int
 n)

                     {

                        
return
 
TaskEx
.Run<
long
>(() => DoSomething(n));

                     }
 
        
private
 
async
 
void
 btnAsync_Click(
object
 sender, 
EventArgs
 e)

                     {

                         lblResult.Text = 
"Start do something..."
;

                         
var
 x = 
await
 DoSomethingAsync(
int
.MaxValue / 2);

                         lblResult.Text = x.ToString();

                     }

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

32

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

7

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

4

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

3

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

2

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

54

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

27

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 8.3万人学习

C 教程
C 教程

共75课时 | 4.4万人学习

C++教程
C++教程

共115课时 | 15.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号