在.NET代码中调用WinRT api

当线程执行同步IO操作时,线程可以阻塞一段不确定的时间。当GUI线程阻塞IO操作直到完成时,用户界面就停止响应用户输入了,比如触摸,鼠标,触笔事件等,让用户失败感。为了保持app可响应,winrt组件通过异步api暴露IO操作的函数。事件上,如果cpu操作大于50毫秒,winrt组件执行计算操作也是通过异步api。具体参考clr via c#第四版第四部分“线程”。

因为winrt api更多的是抽象硬件,很多api执行IO执行都是异步的。为了快速理解,看下面的C#代码:

public static void WinRTAsyncIntro() {
IAsyncOperation<StorageFile> asyncOp = KnownFolders.MusicLibrary.GetFileAsync("Song.mp3");
asyncOp.Completed = OpCompleted;
// Optional: call asyncOp.Cancel() sometime later
}
// NOTE: Callback method executes via GUI or thread pool thread:
private static void OpCompleted(IAsyncOperation<StorageFile> asyncOp, AsyncStatus status) {
if (status == AsyncStatus.Canceled) {
// Process cancellation...
} else {
try {
StorageFile file = asyncOp.GetResults(); // Throws if operation failed
// Process result (do something with file)...
}
catch (Exception ex) {
// Process exception...
}
}
asyncOp.Close();
}



WinrtasyncIntro 函数执行winrt的GetFileasync()方法在用户的音乐库中找文件。所有的winrt api如果执行的是异步操作,那方法名都带有async后缀,而且返回的对象都实现了Winrt的IasyncXxx 接口。上例中,IasyncOperation<tresult>接口的tresult是StorageFile 类型,在这个对象中,引用了asyncOp 变量,表示挂起的异步操作。你的代码必须以某种方式接收操作完成的通知,必须用delegate实现一个回调方法(比如OpCompleted方法),并且将这个delegate赋值给asyncOp的Completed属性。这样当操作完成时,回调方法就会通过某个线程被调用(不需要是GUI线程)。如果操作在赋值给OnCompleted前完成,系统会尽快调用回调,换句话说,这里有一个竞争条件,但是未实现IasyncXxx接口的对象为你解决了竞争,确保你的代码正确执行。
注意最后的WinrtasyncIntro方法,如果你相取消挂起的操作,你可以选择性地调用所有IasyncXxx接口提供的Cancel方法。所有异步操作完成的原因可能有3种:1,操作成功完成;2,操作被显式取消;3,操作失败。无论哪种原因,系统都会调用回调方法,传一个Xxxxasync方法的引用和一个asyncStatus。在OnCompleted方法中,我检查了状态参数和进程是否成功完成,显式取消,或失败。  IasyncInfo接口提供了一个状态属性,此属性包含了与传给回调方法的状态参数相同的值,因为参数是值传递的方式,如果你访问这个参数而不是查询IasyncInfo 的Status属性,你的应用程序的性能会更好,因为查询此属性导致调用winrt api(RCW)。

注意处理完操作完成事件后,IasyncXxx 接口的对象应该用Close清理掉。

下图展示了Winrt的IasyncXxx 接口。这4个主要的接口都继承自IasyncInfo接口。有2个Iasyncaction 接口暴露了一个返回void类型的Getresults 方法。如果操作失败,方法会抛出异常,你可以catch来恢复正确代码。另2个Iasyncaction 接口暴露了一个返回非void的Getresults 方法。

2个IasyncXxxWithprogress 接口允许你的代码接收定期的进度更新状态。大多数异步操作不提供进度更新,但是有些有,比如下载,上传。如果要接收定期进度更新,需要定义另一个回调方法,创建一个delegate赋值给IasyncXxxWithprogress 对象的progress属性。当回调被执行时,会传一个参数。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值