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.

与WinRT组件进行操作的更多相关文章

  1. 使用 C++ WinRT 组件

    创建 C++ WinRT 组件 通过 Cpp/WinRT 项目模板创建一个 WinRT 组件工程 CppWinrtComponent.vcxproj,主要接口定义如下: namespace CppWi ...

  2. [UWP] 为WinRT组件创建Nuget包

    Nuget 是 dotnet 开发中必不可少的包管理工具,但不仅仅局限于 dotnet 项目,在 VS 中使用 C++ 开发的时候,也可以使用 Nuget 来引用第三方组件.同样也可以用 Nuget ...

  3. 使用 iview Table 表格组件修改操作的显示隐藏

    使用 iview Table 表格组件修改操作的显示隐藏,如下图 1.如何设置 table 操作按后台传入的状态值去渲染 不同的按钮? 解决方法 我们在vue2中,动态渲染html 使用的是 retu ...

  4. elementUI的动态tabs页的使用,vue的动态组件的操作

    elementUI的动态tabs页的使用,vue的动态组件的操作 有时候我们需要用到动态的tab页,结合不同的页面内容来显示.这里是使用了elementUI的动态tabs页来实现的 <div c ...

  5. WP8.1中C++的winodws运行时组件位移操作的差异

    最近学习WP8.1应用开发,想把C语言的SM3国密算法移植到手机app中.由于把C语言的代码转换成C#代码工作量较大,因此只能用winodws运行时组件来实现. SM3国密算法是一种HASH算法,具体 ...

  6. vue的组件小操作

    项目技术: webpack + vue + element + axois (vue-resource) + less-loader+ ... vue的操作的方法案例: 1.数组数据还未获取到,做出预 ...

  7. C#使用第三方组件Epplus操作Excel表

    Epplus操作Excel基础详解 1.什么是Epplus Epplus是一个使用Open Office XML文件格式,能读写Excel2007/2010文件的开源组件,在导出Excel的时候不需要 ...

  8. C# 开源组件--Word操作组件DocX

    使用模版生成简历 读写表格数据 合并单元格 工具源代码下载 学习使用 使用模版生成简历 下面将以一个简历实例来讲解DocX对表格的操作,先看看生成的效果 private static void Cre ...

  9. 【Ngui 学习系列之一:简单组件的操作】

    一.Buttonunity edit: Sprite作为父对象和背景 -- Collider -- Button script Label 作为子对象和显示文字代码: private UIButton ...

随机推荐

  1. Java入门 - 高级教程 - 06.邮件收发

    原文地址:http://www.work100.net/training/java-email.html 更多教程:光束云 - 免费课程 邮件收发 序号 文内章节 视频 1 概述 2 发送一封简单的邮 ...

  2. Redis(三):set/get 命令解析

    经过前两篇的介绍,我们对整个redis的动作流程已经有比较清晰的认识. 接下来就是到具体的命令处理方式的理解了,想来我们用这些工具的意义也是在此.虽然没有人觉得,一个set/get方法会有难度,但是我 ...

  3. Qt Installer Framework翻译(7-1)

    配置文件 配置文件可自定义安装程序的用户界面和行为.该文件通常称为config.xml,位于config文件夹中. 最小配置文件由一个<Installer>根元素组成,<Name&g ...

  4. Python-直接存储类实例作为序列的元素

    如果我们需要存储的数据有很多属性,并且存储的数量很多,可选择定义一个类来表示数据类型,而类的实体作为单个的成员进行存储,这样做的好处是可以只存储一个容器,而不需要每次都存储大量的数据,并且可以限制对数 ...

  5. [集训]Trominoes,钩子公式运用

    题意 用这四种骨牌密铺n*m的正方形矩阵,可以不选,求方案数.n*m<=1E8.多组询问. 思考 用如上的表达难以进行计算,尝试转化为一种新的组合解释. 若从右上角开始填起,我们强制要求里面的轮 ...

  6. 使用ob缓存简单实现页面静态化

    <?php //接收新闻id,传统的方法查询数据库并显示数据 $id=intval($_GET['id']); //先判断该新闻对于的静态页面是否存在,如果有,则直接返回,如果 //没有,则查询 ...

  7. Oracle数据库安装与卸载

    一.下载俩个压缩包,同时选中解压到一个文件夹中 二.点击step.exe(win10可能弹出不满足环境要求,选择是就行了) 三.把接收更新勾掉不需要 四.选择创建和配置数据库 五.选择服务器类 六.选 ...

  8. python学习Day02

    [主要内容] 1. 循环. while循环 while 条件: 代码块(循环体) 执行流程: 1. 判断条件是否为真. 如果真. 执行代码块 2. 再次判断条件是否为真...... 3. 当条件为假. ...

  9. 第四次作业:使用Packet Tracer理解RIP路由协议及ICMP协议

    0 个人信息 张樱姿 201821121038 计算1812 1 实验目的 理解RIP路由表的建立与更新 感受RIP坏消息传得慢 2 实验内容 使用Packet Tracer,正确配置网络参数,使用命 ...

  10. Codeforces_851

    A.分三种情况. #include<bits/stdc++.h> using namespace std; int n,k,t; int main() { ios::sync_with_s ...