创建一个简单的组件在C#或Visual Basic,把它从JavaScript

来源:互联网 发布:国家文件数据怎么保存 编辑:程序博客网 时间:2024/05/23 23:42

本演练演示如何使用。NET框架4.5,Visual Basic或C#创建自己的Windows运行时类型,打包在Windows运行时组件,以及如何从Windows Store应用程序专为Windows中使用JavaScript调用该组件。

Visual Studio可以很容易地添加Windows编写的C#或Visual Basic到您的应用程序的运行时组件,并创建Windows运行时类型,你可以从JavaScript中调用。在内部,您的Windows运行时类型可以使用任何。NET Framework的功能,允许在Windows Windows Store的应用程序。(有关详细信息,请参阅创建Windows运行时组件在C#和Visual Basic中。NET Windows Store应用程序的概述。)外部,你的类型可以使Windows运行时它们的参数和返回值的类型。当您构建解决方案时,Visual Studio生成。NET框架的Windows运行时组件项目,然后执行步骤,创建一个Windows元数据(。winmd)的文件。这是您的Windows运行时组件,Visual Studio将包含在您的应用程序。

注意 注意

。NET Framework会自动将一些常用的。NET Framework类型,如原始数据类型和集合类型,映射到自己的Windows运行时的等值。在Windows运行时组件的公共接口,可以使用这些。NET Framework类型,并会出现相应的Windows运行时类型的组件的用户。请参阅创建Windows运行时组件,在C#和Visual Basic。

本演练阐释了以下任务。当你已经完成了第一部分,它建立了Windows Store的应用程序使用JavaScript,你可以以任何顺序完成余下的部分。

  • 创建一个简单的Windows运行时类

  • 使用Windows运行JavaScript和托管代码

  • 从组件返回托管类型

  • 声明事件

  • 公开异步操作

先决条件:

您需要以下来完成本演练:

  • Windows 8的

  • 微软的Visual Studio 2012或Microsoft Visual Studio Express的2012年Windows 8的

创建一个简单的Windows运行时类

本节专为Windows中使用JavaScript创建一个Windows Store应用程序,并增加了一个Visual Basic或C#Windows运行时组件项目。它显示了如何定义一个托管的Windows运行时类型,从JavaScript中创建一个实例的类型,并调用静态方法和实例。示例应用程序的可视化显示的是故意平淡组件上的焦点。随意做出更漂亮。

  1. 在Visual Studio中创建一个新的的JavaScript项目:在菜单栏上,选择“ 文件“新的项目(在Visual Studio Express的2012年为Windows 8中,选择“ 文件““新建项目”)。在已安装的模板“部分的“ 新建项目 “对话框中,选择” 使用Javascript“ ,然后选择Windows Store的。(如果Windows Store的是不可用的,确保您使用的是Windows 8)的项目名称,选择空白的应用程序模板,并进入SampleApp

  2. 创建组件项目:在“ 解决方案资源管理器“中,打开的快捷菜单中的SampleApp的解决方案,选择添加,然后选择“ 新建项目添加一个新的C#或Visual Basic项目的解决方案。在已安装的模板“部分的“添加新项目 “对话框中,选择的Visual BasicVisual C#中,然后选择“ Windows Store的。的Windows运行时组件模板选择,并输入SampleComponent的项目名称。

  3. 更改实例的类的名称。请注意,默认情况下,类标记公众密封的公开为NotInheritable在Visual Basic)。所有的Windows运行时类,你暴露你的组件必须是密封的。

  4. 将两个简单委员添加的类,一个静态方法(在Visual Basic中的共享方法)和实例属性:

    C#
    VB
    namespace SampleComponent{    public sealed class Example    {        public static string GetAnswer()         {             return "The answer is 42.";         }        public int SampleProperty { get; set; }    }}
  5. 可选:要启用智能感知新加入的成员,在“解决方案资源管理器”,在打开的快捷菜单的SampleComponent项目,然后选择“生成”

  6. 解决方案资源管理器中的JavaScript项目中,打开的快捷菜单参考,然后选择“ 添加引用“打开参考管理。选择解决方案,然后选择“ 项目“。选择的的复选框的SampleComponent项目,并选择“确定”添加引用。

Hh779077.collapse_all(EN-US,VS.110)。从JavaScript中调用组件

要使用Windows从JavaScript的运行时类型,添加下面的代码结束时的Default.js文件(以js文件夹中的项目),在现有的功能所提供的Visual Studio模板:

var exfunction basics1() {    document.getElementById('output').innerHTML =        SampleComponent.Example.getAnswer();    ex = new SampleComponent.Example();    document.getElementById('output').innerHTML += "<br/>" +         ex.sampleProperty;}function basics2() {    ex.sampleProperty += 1;    document.getElementById('output').innerHTML += "<br/>" +         ex.sampleProperty;}

请注意,每个成员的名字的第一个字母改为大写转换为小写。这一转变是JavaScript提供的支持,以使自然使用的Windows运行时的一部分。命名空间和类的名称为Pascal大小写。会员名是Camel大小写,除了事件名称,都是小写的。请参阅使用Windows运行在JavaScript中。骆驼外壳的规则可能会造成混淆。通常会出现一系列的首字母大写字母为小写,但如果有三个大写字母,一个小写字母,只有前两个字母出现在小写:例如,一个成员IDStringKind出现作为idStringKind的。在Visual Studio中,你可以建立你的Windows运行时组件项目,然后在你的JavaScript项目中的智能感知,才能看到正确的外壳。

以类似的方式,NET框架提供了支持,使自然的Windows运行在托管代码中使用。这是在本文的后续部分讨论,并在文章中创建Windows运行时组件在C#和Visual Basic中。NET框架支持Windows Store的应用程序和Windows运行时。

Hh779077.collapse_all(EN-US,VS.110)。创建一个简单的用户界面

在你的JavaScript项目,打开的的default.html文件和更新的身体,如下面的代码所示。此代码的示例应用程序包含了一套完整的控制和指定的函数名的点击事件。

<BODY>    <div id="buttons">        <button onclick="basics1();"> 1 </按钮>        <button onclick="basics2();"> 2 </按钮>                <button onclick="runtime1();">运行1 </按钮>        <button onclick="runtime2();">运行2 </按钮>        <button onclick="returns1();">返回1 </按钮>        <button onclick="returns2();">返回2 </按钮>        <button onclick="events1();">活动1 </按钮>        <button id="btnAsync" onclick="asyncRun();">异步</按钮>        <button id="btnCancel" onclick="asyncCancel();" disabled="disabled">取消异步</按钮>        <progress id="primeProg" value="25" max="100" /> yellow;"> </的进展>    </ DIV>    <div id="output">            </ DIV></ BODY>

在你的JavaScript项目,在css文件夹,打开的是default.css身体部分修改,并添加样式来控制按钮的布局和输出文本的位置。

body{    -ms-grid-columns: 1fr;    -ms-grid-rows: 1fr 14fr;    display: -ms-grid;}#buttons {    -ms-grid-rows: 1fr;    -ms-grid-columns: auto;    -ms-grid-row-align: start;}#output {    -ms-grid-row: 2;    -ms-grid-column: 1;}

Hh779077.collapse_all(EN-US,VS.110)。生成并运行应用程序

要建立和运行解决方案,选择F5键。(如果你得到一个运行时错误讯息,指出,SampleComponent是不确定的,缺少的类库项目的引用)。

Visual Studio的第一个编译的类库,然后执行的MSBuild任务,运行Winmdexp.exe(Windows运行时元数据导出工具)来创建您的Windows运行时组件。该组件包括在一个的。winmd文件,它包含两个托管的代码和Windows元数据描述了代码。WinMdExp.exe生成生成错误消息,当您写的代码在Windows运行时组件是无效的,并在Visual Studio IDE中显示的错误消息。Visual Studio会将您的组件为您的Windows Store应用程序的应用程序包(APPX文件),并生成相应的清单。

1按钮选择基础分配到输出区域从静态的getAnswer方法的返回值,创建一个示例类的实例,并显示在输出区域,其SampleProperty财产的价值。

选择的基础按钮增加值的SampleProperty属性,并显示新值,在输出区域。基本类型,如字符串和数字可以作为参数类型和返回类型,并且可以通过托管代码和JavaScript之间。因为在JavaScript中的数字都存储在双精度浮点格式,将它们转换为。NET Framework数字类型。

注意 注意

默认情况下,你可以设置断点,只有在你的JavaScript代码。要调试您的Visual Basic或C#代码,在C#和Visual Basic中创建Windows运行时组件。

要停止调试并关闭您的应用程序,从应用程序切换到Visual Studio,选择“ Shift + F5“ 

使用Windows运行JavaScript和托管代码

Windows运行时可以调用JavaScript或托管代码。Windows运行时对象可以在两者之间来回传递,并可以从任何一方处理事件。你使用的是Windows两种环境中的运行时类型,但如何在一些细节上有所不同,因为JavaScript和。NET Framework的支持在Windows运行时不同。下面的示例演示了这些差异,使用Windows.Foundation.Collections.PropertySet类。在这个例子中,你创建的PropertySet集合在托管代码中的一个实例,并注册了一个事件处理程序集合中的跟踪更改。然后添加JavaScript代码,得到的收集,注册自己的事件处理程序,并使用该集合。最后,添加一个方法,使得对集合的更改从托管代码和Javascript的处理托管异常。

SampleComponent项目中,添加一个新的公共密封类(在Visual Basic中公开为NotInheritable类)命名PropertySetStats。类封装了一个的PropertySet收集,和处理其MapChanged的事件。该事件处理程序跟踪发生的各种变化,和的DisplayStats方法产生一个被格式化的HTML报告。请注意,额外的语句(在Visual Basic中的进口声明);小心地添加到现有的报表,而不是覆盖。

using Windows.Foundation.Collections;namespace SampleComponent{    public sealed class PropertySetStats    {        private PropertySet _ps;        public PropertySetStats()        {            _ps = new PropertySet();            _ps.MapChanged += this.MapChangedHandler;        }        public PropertySet PropertySet { get { return _ps; } }        int[] counts = { 0, 0, 0, 0 };        private void MapChangedHandler(IObservableMap<string, object> sender,            IMapChangedEventArgs<string> args)        {            counts[(int)args.CollectionChange] += 1;        }        public string DisplayStats()        {            StringBuilder report = new StringBuilder("<br/>Number of changes:<ul>");            for (int i = 0; i < counts.Length; i++)            {                report.Append("<li>" + (CollectionChange)i + ": " + counts[i] + "</li>");            }            return report.ToString() + "</ul>";        }    }}

该事件处理程序如下熟悉的。NET Framework事件模式,除了事件的发送者(在这种情况下,的PropertySet对象)转换的IObservableMap <string,在Visual Basic中的对象接口(IObservableMap(字符串,对象)),这是视窗运行时和接口IObservableMap <K, V>的实例化。(你可以使用这个发送者的类型,如果必要的。)此外,作为一个接口,而不是作为一个对象的事件参数。

在Default.js文件,添加Runtime1的功能,如下图所示。此代码创建一个PropertySetStats对象,得到它的PropertySet收集,并添加自己的事件处理程序,onMapChanged的功能,处理的MapChanged事件。对集合的更改后,runtime1调用的DisplayStats的方法来显示一个概要的变化类型。

var propertysetstatsfunction runtime1() {    document.getElementById('output').innerHTML = "";    propertysetstats = new SampleComponent.PropertySetStats();    var propertyset = propertysetstats.propertySet;    propertyset.addEventListener("mapchanged", onMapChanged);    propertyset.insert("FirstProperty", "First property value");    propertyset.insert("SuperfluousProperty", "Unnecessary property value");    propertyset.insert("AnotherProperty", "A property value");    propertyset.insert("SuperfluousProperty", "Altered property value")    propertyset.remove("SuperfluousProperty");    document.getElementById('output').innerHTML +=        propertysetstats.displayStats();}function onMapChanged(change) {    var result    switch (change.collectionChange) {        case Windows.Foundation.Collections.CollectionChange.reset:            result = "All properties cleared";            break;        case Windows.Foundation.Collections.CollectionChange.itemInserted:            result = "Inserted " + change.key + ": '" +                 change.target.lookup(change.key) + "'";            break;        case Windows.Foundation.Collections.CollectionChange.itemRemoved:            result = "Removed " + change.key;            break;        case Windows.Foundation.Collections.CollectionChange.itemChanged:            result = "Changed " + change.key + " to '" +                 change.target.lookup(change.key) + "'";            break;    }    document.getElementById('output').innerHTML +=        "<br/>" + result;}

处理Windows运行在JavaScript中的事件是非常不同的方式处理它们的方式。NET Framework的代码。JavaScript事件处理程序中只需要一个参数。当你在Visual Studio调试器,查看此对象的一个​​属性是发送者。事件参数接口的成员也直接出现在该对象。

为了运行应用程序,选择F5键。如果这个类不是密封的,你得到的错误信息,“导出未密封的的类型”SampleComponent.Example“目前不支持。为密封的,请注明。”

选择运行1按钮。该事件处理程序显示的元素被添加或更改,并在年底的DisplayStats方法被调用时产生的汇总数的变化。要停止调试并关闭该应用程序,切换到Visual Studio,选择“ Shift + F5

要添加两个项目的PropertySet从托管代码的集合,添加下面的代码的PropertySetStats类:

C#
VB
     
      public void AddMore()        {            _ps.Add("NewProperty", "New property value");            _ps.Add("AnotherProperty", "A property value");        }

此代码突出了另一个不同的方式,你使用的是Windows两种环境中的运行时类型。如果你输入自己的代码,你会发现,IntelliSense不显示插入的方法,你在JavaScript代码中使用。相反,它显示了常见的添加方法。NET框架中的集合。这是因为一些常用的集合接口有不同的名称,但在Windows运行库和。NET框架类似的功能。当你在托管代码中使用这些接口时,出现。NET框架现金等价物的。这是讨论在C#和Visual Basic中创建Windows运行时组件。当你在JavaScript中使用相同的接口,唯一的变化是从Windows运行时的成员名称的开头大写字母变成小写。

最后,要调用异常处理的AddMore方法,添加的runtime2的功能到default.js。

function runtime2() {    try {        propertysetstats.addMore();    }    catch (ex) {        document.getElementById('output').innerHTML +=            "<br/><b>" + ex + "</b>";    }    document.getElementById('output').innerHTML +=        propertysetstats.displayStats();}

为了运行应用程序,选择F5键。选择运行,然后运行2。JavaScript事件处理程序报告到集合中的第一个变化。第二个变化,但是,有一个重复键。用户的。NET Framework字典期望的添加方法抛出一个异常,这是发生了什么。Javascript的处理。NET Framework异常。

注意注意

从JavaScript代码,你可以不显示异常的消息。消息文本被替换为一个堆栈跟踪。欲了解更多信息,请参阅“抛出异常” 在C#和Visual Basic中创建Windows运行时组件。

与此相反,当JavaScript被称为一个重复键插入方法,该项目的值被改变了。这种行为差异是由于不同的方式,JavaScript和。NET Framework的支持在Windows运行时,在C#和Visual Basic中创建Windows运行时组件。

从组件返回托管类型

如前所述,您可以通过本机Windows运行时类型来回自由之间的JavaScript代码和C#或Visual Basic代码。大部分的时间,类型名称和成员名称将是相同的在这两种情况下(除非该成员的名字开始在JavaScript中的小写字母)。然而,在上一节中,出现的PropertySet类在托管代码中具有不同的成员。(例如,在JavaScript中,你所谓的插入方法,并在你所谓的添加方法。NET Framework的代码)。本节将探讨这些差异影响的方法。NET Framework类型传递到JavaScript。

除了 ​​让Windows运行时类型中创建您的组件或通过您的组件从JavaScript中,你可以在托管代码中创建一个托管类型,返回给JavaScript就好像它是对应的Windows运行时类型。即使是在第一次运行时类的,简单的例子,参数和返回类型的成员是Visual Basic或C#基本类型,这是。NET Framework类型。为了证明这一点,用于收藏,添加下面的代码示例类,创建一个方法,返回一个泛型字典的字符串,索引的整数:

C#
VB
   
    public static IDictionary<int, string> GetMapOfNames()        {            Dictionary<int, string> retval = new Dictionary<int, string>();            retval.Add(1, "one");            retval.Add(2, "two");            retval.Add(3, "three");            retval.Add(42, "forty-two");            retval.Add(100, "one hundred");            return retval;        }

请注意,字典必须返回一个接口,是通过字典< TKEY,TValue >,并映射到Windows运行时的界面。在这种情况下,该接口是的IDictionary的<int,字符串>IDictionary的(整数,字符串)在Visual Basic)。当Windows运行时类型IMAP <int,字符串>传递给托管代码,它显示为IDictionary的<int,字符串>,和托管类型传递到JavaScript时,情况正好相反。

重要注意事项重要

当一个托管类型实现多个接口,JavaScript使用列表中的第一个出现的界面。例如,如果你返回词典<int,字符串>的JavaScript代码,它显示为IDictionary的<int,字符串>无论哪个界面,您指定的返回类型。这意味着,如果接口不包括后界面上会出现一个成员,该成员是不可见的为JavaScript。

为了测试新的方法和使用的字典,添加的回报returns2的功能到default.js:

var namesfunction returns1() {    names = SampleComponent.Example.getMapOfNames();    document.getElementById('output').innerHTML = showMap(names);} ct = 7function returns2() {    if (!names.hasKey(17)) {        names.insert(43, "forty-three");        names.insert(17, "seventeen");    }    else {        var err = names.insert("7", ct++);        names.insert("forty", "forty");    }    document.getElementById('output').innerHTML = showMap(names);} function showMap(map) {    var item = map.first();    var retval = "<ul>";        for (var i = 0, len = map.size; i < len; i++) {        retval += "<li>" + item.current.key + ": " + item.current.value + "</li>";        item.moveNext();    }    return retval + "</ul>";}

有一些有趣的东西,观察到该JavaScript代码。首先,它包含在HTML中显示的内容的字典的一个showMap功能。在的代码showMap,请注意迭代模式。。NET框架中,有没有通用的IDictionary接口的第一个方法,返回的大小属性,而不是一个大小方法。到JavaScript中,IDictionary的<int,字符串>似乎是在Windows运行时类型IMAP <int,字符串>。(请参阅IMAP <K,V>的接口。)

returns2功能,在前面的例子中,JavaScript调用插入方法(插入 JavaScript中)将项目添加到字典中。

为了运行应用程序,选择F5键。要创建和显示的初始内容的字典,选择返回按钮。要添加多个条目的词典,选择返回2个按钮。请注意,显示的条目中插入的顺序,你会期望从Dictionary <TKey, TValue>的。如果你希望他们排序,你可以返回一个的SortedDictionary <int,字符串>GetMapOfNames。(在前面的例子中使用的PropertySet类具有不同的内部组织从Dictionary <TKey, TValue>的。)

当然,JavaScript是不是一个强类型的语言,使用强类型的泛型集合,可能会导致一些令人惊讶的结果。再次选择返回2个按钮。Javascript的乖乖胁迫“7”的数字7,数字7 克拉为一个字符串存储在。它强制转换的字符串“40”至零。但是,这仅仅是个开始。选择返回按钮几次。在托管代码中,添加的方法会产生重复键的例外情况外,即使值被转换为正确的类型。与此相反,插入方法的更新与现有键关联的值返回一个布尔值,指示是否一个新的密钥被添加到字典中。这就是为什么不断变化的关联的值的关键7。

另一个意外的行为:如果你作为一个字符串参数传递一个未分配的JavaScript变量,你得到的是字符串“undefined”。总之,要小心,当你通过。NET Framework集合类型的JavaScript代码。

注意注意

如果你有大量的文字来连接,你可以做更有效的移动代码的。NET Framework方法和使用的StringBuilder类,所示,在showMap功能。

虽然可以不暴露自己的泛型类型从Windows运行时组件,你可以返回。NET框架的通用集合为Windows运行时类使用如下面的代码:

C#
VB
      
  public static object GetListOfThis(object obj)        {            Type target = obj.GetType();            return Activator.CreateInstance(typeof(List<>).MakeGenericType(target));        }

名单<T>实现IList <T>的,这似乎为Windows运行时类型IVector的<T>在JavaScript中。

声明事件

你可以声明事件,通过使用标准的。NET Framework的Windows运行时使用的事件模式或其他模式。之间的等价性的系统。NET Framework的支持 EventHandler的TEventArgs的代表和Windows运行的EventHandler <T>代表,因此,使用EventHandler的TEventArgs是一个很好的方式来实现的标准。NET Framework模式。要了解其工作原理,添加下面的对类的SampleComponent项目的:

C#
VB
namespace SampleComponent{    public sealed class Eventful    {        public event EventHandler<TestEventArgs> Test;        public void OnTest(string msg, long number)        {            EventHandler<TestEventArgs> temp = Test;            if (temp != null)            {                temp(this, new TestEventArgs()                {                    Value1 = msg,                    Value2 = number                });            }        }    }    public sealed class TestEventArgs    {        public string Value1 { get; set; }        public long Value2 { get; set; }    }}

当你暴露在Windows运行时的事件,事件参数类继承自系统对象。它不会继承系统的EventArgs EventArgs的,因为它会的。NET Framework,因为这个不是Windows运行时类型。

注意注意

如果你声明的自定义事件访问事件(在Visual Basic中的自定义关键字),您必须使用Windows运行时事件模式。在Windows运行时组件的自定义事件和事件的访问。

要处理的测试活动,活动1功能default.js。活动1功能的测试活动,创建一个事件处理函数和,立即调用OnTest引发事件的方法。如果你身体的事件处理程序中放置一个断点,你可以看到,单参数传递的对象包括源对象的两个成员TestEventArgs

var ev;function events1() {    ev = new SampleComponent.Eventful();    ev.addEventListener("test", function (e) {        document.getElementById('output').innerHTML = e.value1;        document.getElementById('output').innerHTML += "<br/>" + e.value2;    });    ev.onTest("Number of feet in a mile:", 5280);}

公开异步操作

NET框架有一组丰富的异步处理和并行处理的工具,基于任务和一般任务< TResult >类的。要在Windows运行时组件暴露的基于任务的异步处理中,使用Windows运行界面IAsyncAction,IAsyncActionWithProgress <TProgress>,IAsyncOperation <TResult>,并IAsyncOperationWithProgress <TResult, TProgress>。(在Windows运行时,操作返回的结果,但操作不)。

本节演示了一个可取消的异步操作,报告进度,并返回结果。GetPrimesInRangeAsync方法使用的AsyncInfo的类来生成一个任务,将其取消和进度报告功能到WinJS.Promise对象的。首先,添加以下语句(在Visual Basic中的进口)的示例类:

C#
VB
using System.Runtime.InteropServices.WindowsRuntime;using Windows.Foundation;

现在添加的GetPrimesInRangeAsync的的方法的示例类:

C#
VB
      
 public static IAsyncOperationWithProgress<IList<long>, double> GetPrimesInRangeAsync(long start, long count)        {            if (start < 2 || count < 1) throw new ArgumentException();            return AsyncInfo.Run<IList<long>, double>((token, progress) =>                Task.Run<IList<long>>(() =>                {                    List<long> primes = new List<long>();                    double onePercent = count / 100;                    long ctProgress = 0;                    double nextProgress = onePercent;                    for (long candidate = start; candidate < start + count; candidate++)                    {                        ctProgress += 1;                        if (ctProgress >= nextProgress)                        {                            progress.Report(ctProgress / onePercent);                            nextProgress += onePercent;                        }                        bool isPrime = true;                        for (long i = 2, limit = (long)Math.Sqrt(candidate); i <= limit; i++)                        {                            if (candidate % i == 0)                            {                                isPrime = false;                                break;                            }                        }                        if (isPrime) primes.Add(candidate);                        token.ThrowIfCancellationRequested();                    }                    progress.Report(100.0);                    return primes;                }, token)            );        }

GetPrimesInRangeAsync是一个非常简单的素数取景器,这是由设计。这里的重点是实现一个异步操作,所以简单是很重要的,缓慢的实现是一个优势时,我们展示的取消。GetPrimesInRangeAsync用蛮力发现的素数:将候选人的所有整数是小于或等于它的平方根,而不是仅使用的素数。步进通过这段代码:

  • 在开始一个异步操作,执行内务管理活动,如无效的输入参数验证和抛出异常。

  • 本实施方案的关键是的AsyncInfo 执行< TResult,工作进度>(FUNC CancellationToken,IProgress<工作进度>,任务< TResult >方法,是方法的唯一参数的委托。代表必须接受取消标记和报告进展情况的接口,并且必须返回一开始的任务,使用这些参数。当JavaScript调用GetPrimesInRangeAsync的方法,下面的步骤发生(未必在给定的顺序):

    • WinJS.Promise对象提供函数来处理返回的结果,作出反应,取消,以及处理进度报告。

    • AsyncInfo.Run方法创建一个取消源和实现IProgress的ţ >接口的对象。的委托,通过取消源,CancellationToken令牌和IProgress ţ >接口。

      注意注意

      如果承诺对象不提供取消功能反应,AsyncInfo.Run还通过一个可取消的道理,而且,取消仍时有发生。承诺对象如果不提供一个函数来处理最新进展,AsyncInfo.Run还提供实现IProgress Ţ,但其报告中被忽略的对象。

    • 代理使用的任务执行< TResult >(FUNC < TResult >,CancellationToken)方法来创建一个启动的任务,它使用令牌和进步接口。代表启动的任务是提供一个lambda函数,计算出所需的结果。在某一时刻。

    • AsyncInfo.Run方法创建对象实现了IAsyncOperationWithProgress的<TResult, TProgress>接口,连接在Windows运行时取消机制与令牌源,并承诺对象的进度报告功能连接的IProgress ţ>接口。

    • IAsyncOperationWithProgress <TResult, TProgress>接口返回给JavaScript。

  • lambda函数,它表示由开始的任务,不带任何参数。因为它是一个lambda函数,它具有访问令牌和IProgress接口。每一次的候选人数量进行评估,lambda函数:

    • 检查以查看是否已达到下一个百分点的进展。如果有,lambda函数调用IProgress的< Ţ 报告方法,而且这一比例通过报告进展情况的功能,无极指定的对象。

    • 使用取消标记抛出一个异常,如果该操作已被取消。如果在IAsyncInfo.Cancel的方法(这的IAsyncOperationWithProgress <TResult, TProgress>接口继承)已被调用,连接,AsyncInfo.Run方法建立确保通知,取消令牌。

  • 当lambda函数返回的素数的列表,该列表被传递,WinJS.Promise指定的对象的处理结果的功能。

要创建JavaScript的承诺,取消机制中,添加asyncRunasyncCancel功能default.js。

var resultAsync;function asyncRun() {    document.getElementById('output').innerHTML = "Retrieving prime numbers.";    btnAsync.disabled = "disabled";    btnCancel.disabled = "";    resultAsync = SampleComponent.Example.getPrimesInRangeAsync(10000000000001, 2500).then(        function (primes) {            for (i = 0; i < primes.length; i++)                document.getElementById('output').innerHTML += " " + primes[i];            btnCancel.disabled = "disabled";            btnAsync.disabled = "";        },        function () {            document.getElementById('output').innerHTML += " -- getPrimesInRangeAsync was canceled. -- ";            btnCancel.disabled = "disabled";            btnAsync.disabled = "";        },        function (prog) {            document.getElementById('primeProg').value = prog;        }    );}function asyncCancel() {        resultAsync.cancel();}

,通过调用的异步GetPrimesInRangeAsync的方法,asyncRun函数创建一个WinJS.Promise的对象。然后该对象的方法有三个功能,处理返回的结果,反应错误(包括取消),并处理进度报告。在这个例子中,返回的结果是在输出区域中打印。取消或完成复位按钮,启动和取消操作。进度报告进度控制。

asyncCancel功能只是调用的取消方法的WinJS.Promise对象。

为了运行应用程序,选择F5键。要启动异步操作,选择异步的按钮。接下来会发生什么取决于您的计算机的速度有多快。如果进度条拉链完成之前,你有时间闪烁,增加的大小,起始号码,是传递到GetPrimesInRangeAsync的,由一个或多个因素的10。您可以调整操作的持续时间增加或减少数字的计数来测试,但在中间加零起始号码将有更大的影响。如果要取消操作,选择取消异步按钮。

原创粉丝点击