首先还是那句话,我不是大牛,这些只是简单的记录一下学习的过程,没有太多面向对象和设计模式的思维,只偏基础,不喜莫笑;个人观点如果有不足之处,还望多多指教!
导语:在Windows 8里面很多API都封装成了异步的形式,因此异步编程成为了Windows 8的一大特色,同时也给Windows 8的应用更好的用户体验和简化了异步编程的复杂度。异步编程在Windows 运行时中是规范,而不是特例。JavaScript、C#、Visual Basic 和 C++ 都各自为异步方法提供了语言支持。
一传统net开发者(传统)与一win8style开发者(win8)的对话
传统:我咋找不到我心爱的MessageBox了我很惆怅!
win8:有啊变形了你可以这样
MessageDialog msgDlg = new MessageDialog("box"); msgDlg.Commands.Add(new UICommand("ok"){ Id=1}); msgDlg.Commands.Add(new UICommand("cancle"){ Id=2}); var result= msgDlg.ShowAsync(); result.Completed= (a1, a2) => { string msg = a1.GetResults().Label; };
传统:狗日的异步了,整的跟ajax似的
win8:微软把你们惯坏了提供一个同步一个异步想把程序员变傻瓜,都懒都整异步 做的东西全部都一卡一卡的自己都受不了,所以痛下决心,把可能浪费时间的全部只提供一个异步
传统:那不是开发起来不类似了,还不是事件还不能补全,是个破委托还得转到定义
win8:不过微软也是相当贴心的!除了俩关键字await asnyc用着俩关键字,让你的用异步就跟用同步差不多
MessageDialog msgDlg = new MessageDialog("box"); msgDlg.Commands.Add(new UICommand("ok"){ Id=1}); msgDlg.Commands.Add(new UICommand("cancle"){ Id=2}); var result=awit msgDlg.ShowAsync();
不过想使用awit方法名必须用asnyc标明
传统:嗯,那么神奇,这变成的就跟同步开发一样了。咋实现的啊!
win8:其实这是个编译器的语法糖;你没做回调其实是你用awit编译器把你的后面的代码自动给你创建一个委托然后把后面的代码放到Completed里面,然后好像是同步,并把返回的结果放到result执行后的结果里面,这样开发起来像同步其实是异步调用
传统:哦原来是这样啊,微软真是太人性化了
附:异步的资料如果需要可以自行阅读,如果研究深层次的原理请继续挖掘这里只是表面
工作原理:WinRT 异步基元
异步方法非常强大,但您可能会对其中的一些工作原理不甚了解。要说明它的工作原理,让我来进一步了解一下异步方法在 WinRT 中的工作方式。我们首先需要调查构建模型所依托的基元。大多数人可能根本不会用到这些基元(如果发现必须使用的情景,我们愿意洗耳恭听此类反馈)。
要从 C# 代码开始,我们需要了解一下 RetrieveFeedAsync 的实际返回类型(C# Intellisense 中显示的内容):
图 1. Intellisense 针对 RetrieveFeedAsync 方法显示的内容
RetrieveFeedAsync 返回 IAsyncOperationWithProgress 接口。IAsyncOperationWithProgress是定义 WinRT 的核心异步编程外观的 5 种接口之一:IAsyncInfo、IAsyncAction、IAsyncActionWithProgress、IAsyncOperation 和IAsyncOperationWithProgress。
WinRT 异步模型的核心接口依托于 IAsyncInfo 而构建。该核心接口可以定义异步操作(例如,当前状态、取消操作的功能和失败操作的错误等)的属性。
如上文所述,异步操作可以返回结果。WinRT 中的异步操作还可以在运行时报告进度。上文中的其他 4 种异步接口(IAsyncAction、IAsyncActionWithProgress、IAsyncOperation 和 IAsyncOperationWithProgress)可以定义不同的结果组合和进度。
提供 Windows 运行时中的核心基元,并允许 C#、Visual Basic、C++ 和 JavaScript 以您熟悉的方式计划 WinRT 异步操作。
请注意:从冷启动迁移到热启动
在 //build/ 大会上发布的 Windows 8 Developer Preview 中,所有 WinRT 中的异步操作都是冷启动。这些操作不会立即运行。它们必须由开发人员专门启动,或在使用 C#、Visual Basic、JavaScript 或 C++ 中的异步功能时隐式启动。我们从不同来源得到反馈显示这种方法并不直观,并且有可能使用户感到痛苦和困惑。
在 Windows 8 Consumer Preview 版本中,您会注意到我们已从 WinRT 异步基元中删除了 Start() 方法。现在,我们的异步操作均使用热启动。因此,异步方法会在将操作返回到调用程序之前启动操作。
除这一更改外,Consumer Preview 中还进行了许多其他的更改,我们根据来自用户的所有重要反馈调整了开发人员平台。
工作原理:结果、取消和异步基元错误
异步操作在 Started 状态下启动,并且可进入其他三种状态之一:Canceled、Completed 和 Error。异步操作的当前状态可在异步操作的 Status 属性中得以体现(以 AsyncStatus 枚举类型表示)。
我们处理异步操作的第一步是连接 Completed 处理程序。在 Completed 处理程序中,我们可以获取结果并使用它们。
IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> op;
op = client.RetrieveFeedAsync(feedUri);
op.Completed = (info, status) =>
{
SyndicationFeed feed = info.GetResults();
UpdateAppWithFeed(feed);
};
有时您可能需要取消操作。您可以通过在异步操作时调用 Cancel 方法来完成该操作。
IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> op;
op = client.RetrieveFeedAsync(feedUri);
op.Cancel();
Completed 处理程序将始终用于调用异步操作,无论其状态是 Completed、Canceled 还是 Error。仅在异步操作的状态为 Completed 时调用 GetResults(例如,在操作状态为 Canceled 或 Error 时不调用)。您可以通过查看状态参数来确定状态。
IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> op;
op = client.RetrieveFeedAsync(feedUri);
op.Cancel();
op.Completed = (info, status) =>
{
if (status == AsyncStatus.Completed)
{
SyndicationFeed feed = info.GetResults();
UpdateAppWithFeed(feed);
}
else if (status == AsyncStatus.Canceled)
{
// Operation canceled
}
};
如果操作失败,则代码依然不够强大。如同取消一样,相同的异步操作也支持错误报告。另外,还可以使用 AsyncStatus 来区分 Completed 和 Canceled 状态,并确定异步操作是否失败(例如,AsyncStatus.Error)。您可以在异步操作的 ErrorCode 属性中找到特定的失败代码。
op.Completed = (info, status) =>
{
if (status == AsyncStatus.Completed)
{
SyndicationFeed feed = info.GetResults();
UpdateAppWithFeed(feed);
}
else if (status == AsyncStatus.Canceled)
{
// Operation canceled
}
else if (status == AsyncStatus.Error)
{
// Error occurred, Report error
}
};
工作原理:使用异步基元报告进度
某些 WinRT 异步操作可以在运行时提供进度通知。您可以使用这些通知向用户报告异步操作的当前进度。
在 WinRT 中,异步报告是通过 IAsyncActionWithProgress<TProgress> 和 IAsyncOperationWithProgress<TResult, TProgress> 接口来处理的。每个接口都包含 Progress 事件,您可以用其来获取异步操作的进度报告。
使用该事件的编程模型与使用 Completed 事件的编程模型类似。在我们检索联合源的示例中,我们可以报告已检索了总量中多少字节的内容:
op = client.RetrieveFeedAsync(feedUri);
float percentComplete = 0;
op.Progress = (info, progress) =>
{
percentComplete = progress.BytesRetrieved /
(float)progress.TotalBytesToRetrieve;
};
在此实例中,第二个参数 (progress) 的类型是 RetrievalProgress。该类型包含两个参数 (bytesRetrieved 和totalBytesToRetrieve),可用于报告我们的当前进度。
有关更为深入的内容(涉及 WinRT 中的异步编程或常规异步),请查看:
结束语
WinRT 中普遍使用异步操作的有趣之处在于其可以影响您构建代码和应用程序的方式。您不禁会认为您的应用程序是以一种更为松散的方式连接的。如果您有此方面的任何反馈,我们将非常乐意倾听!请通过在此处或开发人员论坛中留言来联系我们。
我们希望您的客户喜欢您的 Windows 8 应用程序。我们希望这些应用程序可以处于活动状态并保持这种状态。另外,我们希望使您创建这些应用程序的过程变得更为轻松。我们希望您能够轻松连接到社交网站、进行云存储、在硬盘上处理文件以及与其他小工具和设备进行通信,同时为您的客户提供另人惊叹的用户体验。