1,原理:

WinRT是一个新的类库,应用程序可以用它访问操作系统的功能.

在内部,WinRT以组件的形式实现.COM Component Object Model…

WinRT使用.net元数据来描述其API

当C#引用COM对象的时候,实际上是获得一个RCW引用,该引用内部引用WINRT组件

类似,将一个CLR对象传递给 WINRT API 实际上时将 CCW引用传递(com callerable Wrapper)

2,投射:====WinRT核心概念

文件名和命名空间: .winmd文件本身的名称必须和包含winrt组件的命名空间匹配. 比如,MyRT.PLC.winmd 文件必须在 MyRT.PLC命名空间或者其子命名空间定义RT组件.

通用基类型.

RT组件不共用基类.CLR投射的时候,感觉像从Object派生

核心数据类型....bool 整数,浮点数,16位字符,字符串和void.

类:支持继承和多态,但是没有使用基本上.

结构: 支持结构. clr进行了某些投射,比如Point,Rect,Size,TimeSpan

可控结构: 将 Foundation.IReference<T>投射成Nullable<T>

枚举: 枚举值作为int传递.有符号时离散型,无符号是标志值类型[flag]

方法:不支持Ref,支持Out(不可以同时输入输出.相当于INOUT)

属性:不支持有参属性和只读属性

委托:只能为参数类型和返回类型指定WinRT组件. WinRT委托没有BeginInvoke和EndInvoke方法

事件:

public delegate void TypedEventHandler<TSender,TResult>(TSender sender,TResult args)
EventHandler<T>

异常:使用HREsult指明状态. CLR投射成异常状态.其HResult属性用来包含HResult值.

字符串:WinRT系统不允许字符串为null.可以传递String.Empty给WinRT API.

日期: Foundation.DateTime结构代表一个UTC时间. CLR将其投射成 DateTimeOffset结构.在实列中,其将UTC时间转换成本地时间,然相反,clr将其作为UTC时间传给WinRT API

URI:WinRT只支持绝对URL

IClosable/IDispose   RT对象映射称为 Dispose方法,注意.Close方法不能执行任何IO操作.所以.需要显示调用存储方法来存储数据.

数组:支持一维0基数组

集合:CLR使用CCW来包装集合. 会跨边界操作.

  •     IITerable<T>   IEnumerable<T>
  •     IVector<T>    IList<T>
  •    IVectorView<T> IReadOnlyList<T>
  • IMap<K,V>           IDictionary<TKey,TValue>
  • IMapView<K,V>     IReadOnlyDictionary<TKey,TValue>
  • IKeyValuePair<K,V>  KeyValuePair<TKey,TValue>

框架投射

       1,从.NET代码中调用异步WinRTAPI  API所在模块地址.

C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Annotated\Windows.winnmd

C:\Windows\SysWOW64\WinMetadataC:\Windows\System32\WinMetadata

  public static void WinRTAsyncIntro()
{
//Provides access to common locations that contain user content.
//This includes content from a user's local libraries (such as Documents, Pictures, Music, and Videos),
//HomeGroup, removable devices, and media server devices.
IAsyncOperation<StorageFile> asyncOp = KnownFolders.MusicLibrary.GetFileAsync("Song.mp3");//在音乐中查找一首歌.
asyncOp.Completed = OpCompleted;
Console.WriteLine("Operation...Completed!");
} private static void OpCompleted(IAsyncOperation<StorageFile> asyncInfo, AsyncStatus asyncStatus)
{
switch (asyncStatus)
{
case AsyncStatus.Completed:
Console.WriteLine("Completed!");
break;
case AsyncStatus.Canceled:
Console.WriteLine("Canceled");
break;
case AsyncStatus.Error:
Exception exception = asyncInfo.ErrorCode;//将异常转化成异常类.
Console.WriteLine("Error"+exception.HResult.ToString());
break;
default:
break; }
}

1该类是个异步操作函数,用来在公共文件夹的音乐库中查找一首歌

2 注意,在函数结束后,线程还在运行(除非进程结束).

3,当线程完成后,触发事件,调用完成函数

在完成函数里面,进行处理:

注意:没有出现显示的异常. 无论任何情况,都会调用完成函数,在完成函数里面处理3中情况

1,正常完成: status=completed

2,任务取消:status=canceled  //调用所有IAsyncXXX提供的Cancel方法.

3,发生异常:status=error 并且  异常的ErrorCode包装成了一个异常类.在其HResult中存放了异常的HResult.

4,在处理完毕所有情况后,调用IAsyncXXX.Close()方法进行资源的清理.

2,注意接口关系

基本接口:

 [GuidAttribute(54, 0, 0, 192, 0, 0, 0, 0, 0, 0, 70)]
[SupportedOn(100794368, Platform.Windows)]
[SupportedOn(100794368, Platform.WindowsPhone)]
[Version(100794368)]
public interface IAsyncInfo
{
[SupportedOn(100794368, Platform.Windows)]
[SupportedOn(100794368, Platform.WindowsPhone)]
void Cancel();
[SupportedOn(100794368, Platform.Windows)]
[SupportedOn(100794368, Platform.WindowsPhone)]
void Close(); [SupportedOn(100794368, Platform.Windows)]
[SupportedOn(100794368, Platform.WindowsPhone)]
Exception ErrorCode { get; }
[SupportedOn(100794368, Platform.Windows)]
[SupportedOn(100794368, Platform.WindowsPhone)]
uint Id { get; }
[SupportedOn(100794368, Platform.Windows)]
[SupportedOn(100794368, Platform.WindowsPhone)]
AsyncStatus Status { get; }
}

AsyncStatus

[SupportedOn(100794368, Platform.Windows)]
[SupportedOn(100794368, Platform.WindowsPhone)]
[Version(100794368)]
public enum AsyncStatus
{
Started = 0,
Completed = 1,
Canceled = 2,
Error = 3
}

几个异步函数比较

IAsyncAction----Task
IAsyncActionWithProgress<TProgress>---带有过程回调
IAsynOperation<Tresut>---带返回参数
IA十一年Operation With Progress<Tresult,TProgress>---带过程回调,带返回参数的异步操作

利用C#提供的async和await简化代码:

 public static async void WinRTAsyncIntroEasy()
{
try
{
StorageFile storageFile = await KnownFolders.MusicLibrary.GetFileAsync("Song.mp3");//正常结果
}//异常完成
catch (OperationCanceledException) { Console.WriteLine("operation is canceled"); }
catch(Exception e) { Console.WriteLine(e.HResult.ToString()); } }

1,要添加引用system.Runtime.WindowsRuntime.dll.

C:\Windows\WinSxS\msil_system.runtime.windowsruntime_* \

2,注意该函数是一个异步函数. 但是在函数内部是同步的.使用await关键字的作用:

1,如果没有await关键字,那么异步操作将导致 GetFileAsync...异步执行,将执行下面的语句.加入await后,函数在这里就返回了,当异步函数没有执行完毕前,其不会执行下面的语句.

2,await进行了数据的转换, 比如    int t=Task<int> XXXAsync() 如果函数正确完成,那么就会将结果返回给t.

3,await在返回后,才继续执行下面的语句.所以,上面的方法,是一个很不错的范式.

 public static async Task TryConnectPlcAsync(CancellationToken token)
{ Plc plc = new Plc(CpuType.Logo0BA8, "192.167.0.0", 0, 1); Task t1 = plc.OpenAsync();//一个PLC异步函数,注意,异步函数的异常只能通过await来接收,它并不会直接导致出错.只是会终止线程. Task t2 = Task.Run(() =>//一种将没有取消功能的异步函数增加取消功能.
{ do
{ log("token is"+token.IsCancellationRequested.ToString());
log(t1.Status.ToString()); if (token.IsCancellationRequested)
{
//token.ThrowIfCancellationRequested();
throw new Exception();
}
if (t1.IsFaulted) throw t1.Exception; } while (true); },token
);
try
{ await t2;
}
catch(Exception e)
{
log(e.Message+"in 1");
//throw; 有的时候,将throw 抛给上层,并且运行完finally之后,就返回.//没的时候,不抛给上层. } finally
{
plc.Close();
Console.WriteLine("plc is closed");
}
//正常完成的情况. Console.WriteLine("ok..."); }
public static async Task TryConnectPLCTest()
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
Task t = TryConnectPlcAsync( token);
Thread.Sleep(100);
//tokenSource.Cancel();用于 给 toekn设定一个取消标志.然后交给异步程序进行处理.(向异步程序传递取消标志).
try
{
await t;//必须在这个地方捕捉错误,否则,异步任务的错误捕捉不到.
Console.WriteLine(t.Status);
}
catch(Exception e)
{
log(e.GetType().ToString());
}
finally
{
tokenSource.Dispose();
}
}

注意1:  取消的用法:建立一个cancellationTokenSource对象,并且将其token传递给异步函数,当设定cancellationTokenSource.Cancel()方法的时候,就会向异步函数的token.IsCancelRequest传递true;

注意2:在异步中发生的错误,需要 await Task 中进行捕捉,否则会捕捉不到

注意3:使用一个包装来强制在取消的时候,抛出,任务取消异常.查看Task t2.

最新文章

  1. JS 工具类
  2. jquery easyui 1.4.1 验证时tooltip 的位置调整
  3. 【转】javax.net.ssl.SSLHandshakeException(Cas导入证书)
  4. Action开发、通配符、路径问题和struts中常量用法
  5. 前端开发必备的Sublime 3插件
  6. 群星云集 BOSS上海时装秀—情沪魅影- 在线观看 - 乐视网
  7. updateMany
  8. apache RewriteCond RewriteRule
  9. VMVare 桥接上网
  10. Linux学习总结(十四)—— 查看CPU信息
  11. hdu 2669 Romantic 扩展欧几里得
  12. css3 背景色 实现边框渐变运动动画
  13. 从头到尾彻底解析Hash 表算法
  14. Python基础语法 系统学习
  15. webmagic 爬取网页所有文章的标题时间作者和内容
  16. JS媒体查询
  17. linux路由
  18. nginx + tomcat = http &amp;&amp; https
  19. 复习C++:VS2008中的宏干嘛用的
  20. C#.NET常见问题(FAQ)-如何让Listbox支持多选

热门文章

  1. python面向对象(一切皆对象)
  2. [bzoj2038] [洛谷P1494] [2009国家集训队] 小Z的袜子(hose)
  3. 优雅写Java之二(数组集合流)
  4. robotframework从列表中循环读取数据,传入关键字执行
  5. 【WPF学习】第二十三章 列表控件
  6. css的字体单位
  7. flask使用blinker信号机制解耦业务代码解决ImportError: cannot import name &#39;app&#39;,以异步发送邮件为例
  8. 机器学习:没有免费午餐定理(No Free Lunch Theorem)
  9. &lt;背包&gt;solution-POJ1742_Coins
  10. Bash 脚本中的 set -euxo pipefail