在.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 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 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是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属性。当回调被执行时,会传一个参数。

在.NET代码中调用WinRT api_第1张图片

你可能感兴趣的:(Windows,Runtime)