C#语言基础之异步编程

背景:
编写异步应用程序的传统技术比较复杂,VS2012引入了简化方法,即使用Async和Await的异步编程,得到.NET Framework4.5和Windows运行时的异步支持。
何时进行异步编程(异步提高响应能力):
异步对可能引起阻塞的活动(应用程序访问Web资源)大有裨益。对Web资源的访问有时会很慢或延迟,如果此类活动发生在同步过程中,则整个应用程序必须得等待,在异步过程中,应用程序可以继续执行其他不依赖Web的资源。
下表显示了异步编程提高响应能力的典型应用场景。 从 .NET Framework 4.5 和 Windows 运行时中列出的 API 包含支持异步编程的方法。

应用程序区域包含异步方法的受支持的API
Web访问HttpClient,SyndicationClient
使用文件StorageFile, StreamWriter, StreamReader, XmlReader
使用图像MediaCapture, BitmapEncoder, BitmapDecoder
WCF编程同步和异步操作

由于所有与用户界面相关的活动通常共享一个线程,因此,异步对访问 UI 线程的应用程序来说尤为重要。 如果在一个同步应用程序中有任何的线程被阻塞了,那么所有线程都将被阻塞。 你的应用程序停止响应,因此,你可能在其等待过程中认为它已经失败。
使用异步方法时,应用程序将继续响应 UI。 例如,你可以调整窗口的大小或最小化窗口;如果你不希望等待应用程序结束,则可以将其关闭。
更容易编写异步方法:
C# 中的 async 和 await 关键字都是异步编程的核心。 通过使用这两个关键字,你可以使用 .NET framework 或 Windows 运行时中的资源轻松创建异步方法(几乎与创建同步方法一样轻松)。
//异步方法签名中需要注意的三点:
//有一个async方法修饰符,如果没有该修饰符,编译器会将该方法等同于同步方法一样对待,不会报错
//返回类型为Task或者Task< TResult >
//约定方法名称以Async为后缀

Using System.Net.Http;
async Task< int > AccessTheWebAsync()
{ 
    //添加引用System.Net.Http 声明client.
    HttpClient client = new HttpClient();

    // GetStringAsync异步方法返回Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}

void DoIndependentWork()
{
   Console.WriteLine("Working ....");
}

如果要求AccessTheWebAsync在调用GetStringAsync和等待其完成任务期间不能进行其他工作,则可以使用下面单个语句中调用和等待来简化代码。

string urlContents=await client.GetStringAsync();

以下特征总结了使上一个示例成为异步方法的原因
1. 方法签名包含一个 Async(VB) 或 async (C#)修饰符。
2. 按照约定,异步方法的名称以“Async”后缀为结尾。
3. 返回类型为下列类型之一:
如果你的方法有操作数为 TResult 类型的返回语句,则为 Task< TResult >。
如果你的方法没有返回语句或具有没有操作数的返回语句,则为Task。
如果你编写的是异步事件处理程序,则为 Void(Visual Basic 中为 Sub)。
4. 方法通常包含至少一个 await 表达式,该表达式标记一个点,在该点上,直到等待的异步操作完成方法才能继续。 同时,将方法挂起,并且控制权返回到方法的调用方。
异步方法中发生的事情:
异步编程中最需要弄清楚的是控制流是如何从一个方法移动到另一个方法的
异步编程中控制流在方法间移动
关系图中的数值对应于以下步骤。
1. 事件处理程序调用并等待 AccessTheWebAsync 异步方法。
2. AccessTheWebAsync 可创建 HttpClient 实例并调用 GetStringAsync 异步方法以下载网站内容作为字符串。
3. GetStringAsync 中发生了某种情况,该情况挂起了它的进程。 可能必须等待网站下载或一些其他阻止活动。 为避免阻止资源,GetStringAsync 会将控制权出让给其调用方 AccessTheWebAsync。
GetStringAsync 返回 Task,其中 TResult 为字符串,并且 AccessTheWebAsync 将任务分配给 getStringTask 变量。 该任务表示调用 GetStringAsync 的正在进行的进程,其中承诺当工作完成时产生实际字符串值。
4.由于尚未等待 getStringTask,因此,AccessTheWebAsync 可以继续执行不依赖于 GetStringAsync 得出的最终结果的其他工作。 该任务由对同步方法 DoIndependentWork 的调用表示。
5.DoIndependentWork 是完成其工作并返回其调用方的同步方法。
6.AccessTheWebAsync 已用完工作,可以不受 getStringTask 的结果影响。 接下来,AccessTheWebAsync 需要计算并返回该下载字符串的长度,但该方法仅在具有字符串时才能计算该值。
因此,AccessTheWebAsync 使用一个 await 运算符来挂起其进度,并把控制权交给调用 AccessTheWebAsync 的方法。 AccessTheWebAsync 将 Task(Of Integer) 或 Task< int > 返回至调用方。 该任务表示对产生下载字符串长度的整数结果的一个承诺。
如果 GetStringAsync(因此 getStringTask)在 AccessTheWebAsync 等待前完成,则控件会保留在 AccessTheWebAsync 中。 如果异步调用过程 (getStringTask) 已完成,并且 AccessTheWebSync 不必等待最终结果,则挂起然后返回到 AccessTheWebAsync 将造成成本浪费。
在调用方内部(此示例中的事件处理程序),处理模式将继续。 在等待结果前,调用方可以开展不依赖于 AccessTheWebAsync 结果的其他工作,否则就需等待片刻。事件处理程序等待 AccessTheWebAsync,而 AccessTheWebAsync 等待 GetStringAsync。
7.GetStringAsync 完成并生成一个字符串结果。 字符串结果不是通过按你预期的方式调用 GetStringAsync 所返回的。(请记住,此方法已在步骤 3 中返回一个任务。)相反,字符串结果存储在表示完成方法 getStringTask 的任务中。 await 运算符从 getStringTask 中检索结果。 赋值语句将检索到的结果赋给 urlContents。
8.当 AccessTheWebAsync 具有字符串结果时,该方法可以计算字符串长度。 然后,AccessTheWebAsync 工作也将完成,并且等待事件处理程序可继续使用。 在此主题结尾处的完整示例中,可确认事件处理程序检索并打印长度结果的值。
如果你不熟悉异步编程,请花 1 分钟时间考虑同步行为和异步行为之间的差异。 当其工作完成时(第 5 步)会返回一个同步方法,但当其工作挂起时(第 3 步和第 6 步),异步方法会返回一个任务值。 在异步方法最终完成其工作时,任务会标记为已完成,而结果(如果有)将存储在任务中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 实现二维平面异步运动可以使用 C# 的 Task 和 async/await 关键字。以下是一个简单的示例代码: ```csharp using System; using System.Threading.Tasks; class Program { static async Task Main() { int x = 0; int y = 0; int dx = 1; int dy = 1; while (true) { Console.SetCursorPosition(x, y); Console.Write("*"); await Task.Delay(100); // 等待一段时间 Console.SetCursorPosition(x, y); Console.Write(" "); x += dx; y += dy; // 如果到达边界则反向移动 if (x <= 0 || x >= Console.WindowWidth - 1) { dx = -dx; } if (y <= 0 || y >= Console.WindowHeight - 1) { dy = -dy; } } } } ``` 这个示例代码中,我们使用了一个无限循环来模拟运动的过程。在每次循环中,我们先将当前位置打印出来,等待一段时间后再将其清除。然后更新位置,并根据是否到达边界来决定是否改变方向。这个示例代码只是简单的演示了异步运动的基本实现方式,你可以根据具体的需求进行修改和扩展。 ### 回答2: C是一种通用的编程语言,广泛应用于软件开发领域。C语言诞生于20世纪70年代初,由美国贝尔实验室的Dennis Ritchie和Ken Thompson开发而成。C语言注重底层编程,提供了丰富的编程工具和强大的功能,被广泛应用于系统软件、嵌入式系统和游戏开发等领域。 C语言具有简洁、高效的特点,适合开发底层操作和性能要求高的程序。它提供了丰富的基本数据类型、运算符和控制语句,可以方便地实现复杂的算法和逻辑。C语言的语法和结构简单易懂,对程序员的编程思维能力提出了高要求,因此被认为是培养程序设计能力的基础。 C语言的跨平台性能优秀,可以在不同的操作系统和硬件平台上运行。它的标准库提供了丰富的函数和数据结构,方便程序员开发各种应用程序。C语言还支持指针操作,可以直接访问内存地址,提供了更大的灵活性和效率。 虽然C语言很强大,但也有一些局限性。它对程序员的编程能力要求较高,需要掌握一些底层的编程知识和技巧。C语言不提供面向对象编程的特性,所以在开发大型复杂的软件项目时可能不太方便。此外,C语言没有内置的垃圾回收机制,需要程序员手动管理内存,容易出现内存泄漏和访问越界等问题。 总的来说,C语言是一种强大而灵活的编程语言,适用于各种类型的程序开发。虽然它的学习曲线较陡,但精通C语言可以为程序员打开更广阔的机会,提升他们的编程能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值