在Windows 8里面很多API都封装成了异步的形式,因此异步编程成为了Windows 8的一大特色,同时也给Windows 8的应用更好的用户体验和简化了异步编程的复杂度。异步编程在Windows 运行时中是规范,而不是特例。JavaScript、C#、Visual Basic 和 C++ 都各自为异步方法提供了语言支持。
许多 Windows 运行时功能,如 MediaCapture 和 StorageFile,都被公开为异步函数。按照惯例,异步函数的名称以 "Async" 结尾,表示当调用已返回后可能会发生其部分执行。
当你在 Metro 风格应用中使用异步 API 时,你的代码将以一致的方式进行非阻止调用。当你在 API 中实现这些异步模式后,调用者可以理解并按照可预知的方式使用你的代码。
下面是一些需要调用异步 Windows 运行时 API 的常见任务。
显示消息对话框。
使用文件系统。
向 Internet 发送数据和从 Internet 接收数据。
有了 Windows 运行时异步 API 以后,你无需明确管理线程或直接与基础实现进行交互。
每种编程语言都按照其自己的方式支持异步模式:
编程语言异步表示形式
JavaScript
承诺对象,then 函数
C#
将来对象,await 运算符
Microsoft Visual Basic .NET
将来对象,Await 运算符
Visual C++ task 类,.then 方法
下面来看一下一个获取网络信息的异步编程的例子
C#版本
UI
CS页面
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Syndication;
namespace AsyncDemo
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();
client.BypassCacheOnRetrieve = true;
Uri feedUri
= new Uri("http://feed.iyunv.com/blog/sitehome/rss");
// 调用异步方法获取网络信息
SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
//下面的代码在异步await 完成之后才开始执行 tb.Text = feed.Title.Text + Environment.NewLine;
foreach (SyndicationItem item in feed.Items)
{
tb.Text += item.Title.Text + ", " +
item.PublishedDate.ToString() + Environment.NewLine;
}
}
}
}
对异步方法 RetrieveFeedAsync 的调用,行 SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) 使用 await 运算符。
假如使用的是同步方法的时候,UI会一直卡住一直等到网络请求完成之后才会释放掉UI的线程。但如果你调用 client.RetrieveFeedAsync,则方法启动检索并立即返回。当你将 await 与 RetrieveFeedAsync 结合使用时,应用临时退出事件处理程序。然后,它便可以在 RetrieveFeedAsync 异步执行时处理其他事件。 这样便可以保持应用对用户进行响应。 当 RetrieveFeedAsync 完成并且 SyndicationFeed 可用时,应用一定会在 SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) 之后重新进入它停止的事件处理程序,并完成方法的剩余部分。
返回异步 API 的类型和结果
如果你跟随指向 RetrieveFeedAsync 的链接,那么你可能会注意到 RetrieveFeedAsync 的返回类型不是 SyndicationFeed。 返回类型为 IAsyncOperationWithProgress 。 异步 API 返回一个包含结果的对象。 尽管该对象很常见,但有时却很有用,若要将异步方法视为可等待的方法,await 运算符实际上对该方法的返回值执行操作,而不是对该方法执行操作。 当你应用 await 运算符时,可以获取异步方法的结果。
当使用异步方法时,你可以通过查看返回值来获取有关其结果的信息。 Windows 运行时中的所有异步 API 都返回以下类型之一:
.NET for Metro style apps 中的异步方法的返回类型为 Task 或 Task。 返回 Task 的方法与 Windows 运行时中返回 IAsyncAction 的异步方法类似。 在任何情况下,异步方法的结果都为 void。 同样,返回类型 Task 类似于 IAsyncOperation,因为异步方法的结果与 TResult 类型参数的类型相同。
下面的是C++的版本
UI
h头文件
#pragma once
#include "MainPage.g.h"
namespace AsyncDemoApp
{
///
/// An empty page that can be used on its own or navigated to within a Frame.
///
public ref class MainPage sealed
{
public:
MainPage();
protected:
virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e) override;
private:
void Button_Click_1(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};
}
cpp
#include "pch.h"
#include
#include "MainPage.xaml.h"
using namespace AsyncDemoApp;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace concurrency;
using namespace Windows::Web::Syndication;