使用C++/CX开发Windows Store应用程序的注意事项

本文探讨了在Windows 8环境下使用C++/CX及WinRT进行应用程序开发时面临的异常处理与性能问题。重点讲解了WinRT与标准C++间的异常处理差异、异步编程中的注意事项以及如何通过减少类型转换来提升性能。

《Diving deep into C++ /CX and WinRT》演讲里,Marian Luparu谈到针对Windows 8的应用程序的异常处理和性能问题。对于开发者来说,最重要的东西是理解WinRT和标准C++代码之间的边界如何影响异常处理和性能。

\

异常处理基础

\

WinRT没有异常的概念,它的内部使用HResult。放在Platform::Exception的派生类之内的调试信息不会跨越ABI边界。通常和异常相关的信息只对调试器可用。

\

C++和SEH风格的异常会在跨越ABI边界的时候中止进程。这意味着所有C++异常都需要处理,即使这意味着只是把它包装到Platform::Exception里。

\

在捕获COMException时一定要检查HResult。如果你不知道如何处理某个HResult,可以重新抛出这个异常。类似的,如果你调用一个COM方法,它返回一个错误代码,你应该马上把它转换成一个Exception。

\

异步和异常处理

\

在使用并行模式库(PPL)时,让Lambda表达式接受一个task对象而不是一个单纯的结果是很重要的。比如说,应该使用

\
\.then( [](Task result) {…} )
\

而不是

\
\.then( [](int result) {…} )
\

如果你使用第二个版本,一旦遇到异常,整个“then”代码块就会被忽略。(译注:关于PPL的异步可以参考《遇见PPL:C++的并行和异步》的第四节《async + continuation》)

\

异步和线程

\

和C#以及VB里的async/await一样,PPL在处理线程时有点繁琐。如果你在UI线程里开始一项操作,那么每个continuation(即“then”代码块)也将在UI线程里执行。如果你想使用线程池,你需要向“then”方法传递task_continuation_context::use_arbitrary参数。

\

C++类 vs WinRT类

\

一般而言,开发者不应该适用WinRT风格的类(ref class),除非他们要和XAML交互或者向其他语言提供WinRT组件而不得不这样做。WinRT类比标准C++类慢,而且不能移植,即无法在标准C++应用程序里使用。

\

另一个改善性能的途径是减少WinRT类型和C++类型之间的转换。虽然频繁的跨越WinRT边界的通讯会很慢,但没有必要的分配内存和复制数据可能更糟。

\

一些诸如StringReference的包装类或许能够缓解性能问题,但使用的时候必须非常小心。StringReference是引用计数的,因此,在StringReference释放之前,它包装的缓冲内容不能被改变或者删除。这个问题会在WinRT持有StringReference的一个副本时出现,你无法预料会出现什么结果。Marian Luparu给出了一个例子:

\
  1. 创建StringReference包装一个缓冲内容。\
  2. 调用一个WinRT函数并传递这个StringReference。\
  3. 这个WinRT函数触发一个C++回调。\
  4. 这个回调修改底层的缓冲内容。\
  5. 控制权回到WinRT函数,但字符串已被意外地修改了。\

ArrayReference也能类似的用来包装C++数组。但由于WinRT并不期望C++数组是不可变的,于是出现问题的机会比较少。

\

查看英文原文:Notes on Writing a Windows Store Apps with C++/CX

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值