Criação de componentes do Windows Runtime em C# e Visual BasicCreating Windows Runtime Components in C# and Visual Basic

Começando com o .NET Framework 4.5, você pode usar código gerenciado para criar seus próprios tipos de tempo de execução do Windows e empacotá-las em um componente de tempo de execução do Windows.Starting with the .NET Framework 4.5, you can use managed code to create your own Windows Runtime types and package them in a Windows Runtime component. Você pode usar o componente nos aplicativos de plataforma Universal do Windows (UWP) que são escritos em C++, JavaScript, Visual Basic, ou C#.You can use your component in Universal Windows Platform (UWP) apps that are written in C++, JavaScript, Visual Basic, or C#. Este tópico descreve as regras para a criação de um componente e descreve alguns aspectos do suporte do .NET Framework para o Windows Runtime.This topic outlines the rules for creating a component, and discusses some aspects of .NET Framework support for the Windows Runtime. Em geral, esse suporte foi projetado para ser transparente para o programador do .NET Framework.In general, that support is designed to be transparent to the .NET Framework programmer. No entanto, ao criar um componente a ser usado com JavaScript ou C++, você precisa estar ciente das diferenças na maneira como essas linguagens dão suporte ao Windows Runtime.However, when you create a component to use with JavaScript or C++, you need to be aware of differences in the way those languages support the Windows Runtime.

Se você estiver criando um componente para usar apenas em aplicativos UWP que são escritos em Visual Basic ou C#, e o componente não contiver controles UWP, em seguida, considere a possibilidade de usar o biblioteca de classes em vez do modelo de Windows Componente de tempo de execução modelo de projeto no Microsoft Visual Studio.If you are creating a component for use only in UWP apps that are written in Visual Basic or C#, and the component does not contain UWP controls, then onsider using the Class Library template instead of the Windows Runtime Component project template in Microsoft Visual Studio. Existem menos restrições em uma biblioteca de classes simples.There are fewer restrictions on a simple class library.

Declaração de tipos em componentes do Windows RuntimeDeclaring types in Windows Runtime Components

Internamente, os tipos de tempo de execução do Windows no seu componente podem usar qualquer funcionalidade do .NET Framework que é permitida em um aplicativo UWP.Internally, the Windows Runtime types in your component can use any .NET Framework functionality that's allowed in a UWP app. Para obter mais informações, consulte .NET para aplicativos UWP.For more info, see .NET for UWP apps.

Externamente, os membros de seus tipos podem expor somente tipos de tempo de execução do Windows para seus parâmetros e valores de retorno.Externally, the members of your types can expose only Windows Runtime types for their parameters and return values. A lista a seguir descreve as limitações nos tipos de .NET Framework que são expostos a partir de um componente de tempo de execução do Windows.The following list describes the limitations on .NET Framework types that are exposed from a Windows Runtime Component.

  • Os campos, os parâmetros e os valores de retorno de todos os tipos públicos e membros no componente devem ser tipos do Windows Runtime.The fields, parameters, and return values of all the public types and members in your component must be Windows Runtime types. Essa restrição inclui os tipos de tempo de execução do Windows que você criar, bem como tipos que são fornecidos pelo Windows Runtime em si.This restriction includes the Windows Runtime types that you author as well as types that are provided by the Windows Runtime itself. Ele também inclui vários tipos do .NET Framework.It also includes a number of .NET Framework types. A inclusão desses tipos faz parte do suporte do .NET Framework fornece para permitir o uso natural do Windows Runtime em código gerenciado—seu código parece usar tipos familiares do .NET Framework em vez dos tipos de tempo de execução do Windows subjacentes.The inclusion of these types is part of the support the .NET Framework provides to enable the natural use of the Windows Runtime in managed code—your code appears to use familiar .NET Framework types instead of the underlying Windows Runtime types. Por exemplo, você pode usar tipos primitivos do .NET Framework, como Int32 e duplo, determinados tipos fundamentais, como DateTimeOffset e Uri , e alguns tipos usados com frequência interface genérica, como IEnumerable<T> (IEnumerable (Of T) no Visual Basic) e IDictionary< TKey, TValue> .For example, you can use .NET Framework primitive types such as Int32 and Double, certain fundamental types such as DateTimeOffset and Uri, and some commonly used generic interface types such as IEnumerable<T> (IEnumerable(Of T) in Visual Basic) and IDictionary<TKey,TValue>. Observe que os argumentos de tipo desses tipos genéricos devem ser tipos de tempo de execução do Windows.Note that the type arguments of these generic types must be Windows Runtime types. Isso é discutido nas seções tipos de passar tempo de execução do Windows para código gerenciado e transmitindo tipos gerenciados para o tempo de execução do Windows, mais adiante neste tópico.This is discussed in the sections Passing Windows Runtime types to managed code and Passing managed types to the Windows Runtime, later in this topic.

  • Classes públicas e interfaces podem conter métodos, propriedades e eventos.Public classes and interfaces can contain methods, properties, and events. Você pode declarar representantes para seus eventos ou usar o EventHandler<T> delegar.You can declare delegates for your events, or use the EventHandler<T> delegate. Uma classe ou interface pública não pode:A public class or interface can't:

    • Ser genérica.Be generic.
    • Implementar uma interface que não é uma interface de tempo de execução do Windows (no entanto, você pode criar suas próprias interfaces do tempo de execução do Windows e implementá-los).Implement an interface that is not a Windows Runtime interface (however, you can create your own Windows Runtime interfaces and implement them).
    • Derivar de tipos que não estão em tempo de execução do Windows, como System. Exception e EventArgs.Derive from types that are not in the Windows Runtime, such as System.Exception and System.EventArgs.
  • Todos os tipos públicos devem ter um namespace raiz correspondente ao nome do assembly, e o nome do assembly não deve começar com "Windows".All public types must have a root namespace that matches the assembly name, and the assembly name must not begin with "Windows".

    Dica.Tip. Por padrão, os projetos do Visual Studio têm os nomes de namespace correspondentes ao nome do assembly.By default, Visual Studio projects have namespace names that match the assembly name. No Visual Basic, a instrução Namespace desse namespace padrão não é mostrada no código.In Visual Basic, the Namespace statement for this default namespace is not shown in your code.

  • As estruturas públicas não podem ter membros que não sejam campos públicos, e esses campos devem ser tipos de valor ou cadeias de caracteres.Public structures can't have any members other than public fields, and those fields must be value types or strings.

  • As classes públicas devem ser sealed (NotInheritable no Visual Basic).Public classes must be sealed (NotInheritable in Visual Basic). Se seu modelo de programação exigir polimorfismo, você pode criar uma interface pública e implementá-la nas classes que deverão ser polimórficas.If your programming model requires polymorphism, then you can create a public interface, and implement that interface on the classes that must be polymorphic.

Depuração do componenteDebugging your component

Se seu aplicativo da UWP e seu componente forem criados com código gerenciado, você pode depurar ambos ao mesmo tempo.If both your UWP app and your component are built with managed code, then you can debug them both at the same time.

Quando você estiver testando o seu componente como parte de um aplicativo UWP usando C++, você pode depurar código gerenciado e nativo ao mesmo tempo.When you're testing your component as part of a UWP app using C++, you can debug managed and native code at the same time. O padrão é somente código nativo.The default is native code only.

Para depurar códigos em C++ nativo e gerenciadoTo debug both native C++ code and managed code

  1. Abra o menu de atalho do projeto do Visual C++ e escolha Propriedades.Open the shortcut menu for your Visual C++ project, and choose Properties.
  2. Nas páginas de propriedades, em Propriedades de Configuração, escolha Depuração.In the property pages, under Configuration Properties, choose Debugging.
  3. Escolha Tipo de Depurador e, na caixa de listagem suspensa, altere Native Only para Misto (Gerenciado e Nativo) .Choose Debugger Type, and in the drop-down list box change Native Only to Mixed (Managed and Native). Escolha OK.Choose OK.
  4. Defina pontos de interrupção nos códigos nativo e gerenciado.Set breakpoints in native and managed code.

Quando você estiver testando o seu componente como parte de um aplicativo UWP usando JavaScript, por padrão a solução está em modo de depuração JavaScript.When you're testing your component as part of a UWP app using JavaScript, by default the solution is in JavaScript debugging mode. No Visual Studio, não é possível depurar JavaScript e código gerenciado ao mesmo tempo.In Visual Studio, you can't debug JavaScript and managed code at the same time.

Para depurar código gerenciado em vez de JavaScriptTo debug managed code instead of JavaScript

  1. Abra o menu de atalho do projeto JavaScript e escolha Propriedades.Open the shortcut menu for your JavaScript project, and choose Properties.
  2. Nas páginas de propriedades, em Propriedades de Configuração, escolha Depuração.In the property pages, under Configuration Properties, choose Debugging.
  3. Escolha Tipo de Depurador e, na caixa de listagem suspensa, altere Script Only para Managed Only.Choose Debugger Type, and in the drop-down list box change Script Only to Managed Only. Escolha OK.Choose OK.
  4. Defina pontos de interrupção no código gerenciado e depure como sempre.Set breakpoints in managed code and debug as usual.

Passagem de tipos do Windows Runtime para código gerenciadoPassing Windows Runtime types to managed code

Conforme mencionado anteriormente na seção tipos de declarativos em componentes de tempo de execução do Windows, determinados tipos do .NET Framework podem aparecer nas assinaturas dos membros de classes públicas.As mentioned previously in the section Declaring types in Windows Runtime Components, certain .NET Framework types can appear in the signatures of members of public classes. Isso faz parte do suporte que o .NET Framework oferece para habilitar o uso natural do Windows Runtime em código gerenciado.This is part of the support that the .NET Framework provides to enable the natural use of the Windows Runtime in managed code. Ele inclui tipos primitivos e algumas classes e interfaces.It includes primitive types and some classes and interfaces. Quando seu componente é usado a partir de JavaScript ou código C++, é importante saber como seus tipos do .NET Framework aparecem para o chamador.When your component is used from JavaScript, or from C++ code, it's important to know how your .NET Framework types appear to the caller. Consulte passo a passo: Criando um componente simples em C# ou Visual Basic e chamando-o por JavaScript para obter exemplos com JavaScript.See Walkthrough: Creating a simple component in C# or Visual Basic and calling it from JavaScript for examples with JavaScript. Esta seção aborda os tipos mais usados.This section discusses commonly used types.

No .NET Framework, tipos primitivos como a Int32 estrutura têm muitas propriedades e métodos úteis, como o TryParse método.In the .NET Framework, primitive types such as the Int32 structure have many useful properties and methods, such as the TryParse method. Por outro lado, tipos primitivos e estruturas no Windows Runtime só têm campos.By contrast, primitive types and structures in the Windows Runtime only have fields. Quando você passa esses tipos para código gerenciado, eles aparentam ser tipos do .NET Framework, e é possível usar as propriedades e os métodos dos tipos do .NET Framework, como faria normalmente.When you pass these types to managed code, they appear to be .NET Framework types, and you can use the properties and methods of the .NET Framework types as you normally would. A lista a seguir resume as substituições que são feitas automaticamente no IDE:The following list summarizes the substitutions that are made automatically in the IDE:

  • Para os primitivos de tempo de execução do Windows Int32, Int64, único, Double, booliano, Cadeia de caracteres (uma coleção imutável de caracteres Unicode), Enum, UInt32, UInt64, e Guid, use o tipo de mesmo nome no namespace System.For the Windows Runtime primitives Int32, Int64, Single, Double, Boolean, String (an immutable collection of Unicode characters), Enum, UInt32, UInt64, and Guid, use the type of the same name in the System namespace.
  • Para UInt8, use byte.For UInt8, use System.Byte.
  • Para Char16, use System. Char.For Char16, use System.Char.
  • Para o IInspectable interface, use System. Object.For the IInspectable interface, use System.Object.

Se C# ou Visual Basic fornece uma palavra-chave de linguagem para qualquer um desses tipos e, em seguida, você pode usar a palavra-chave de idioma em vez disso.If C# or Visual Basic provides a language keyword for any of these types, then you can use the language keyword instead.

Além de tipos primitivos, alguns tipos do Windows Runtime básicos mais usados são exibidos em código gerenciado como os equivalentes do .NET Framework.In addition to primitive types, some basic, commonly used Windows Runtime types appear in managed code as their .NET Framework equivalents. Por exemplo, suponha que seu código JavaScript Use a Windows.Foundation.Uri classe e você quiser passá-lo para um C# ou o método do Visual Basic.For example, suppose your JavaScript code uses the Windows.Foundation.Uri class, and you want to pass it to a C# or Visual Basic method. O tipo equivalente em código gerenciado é o .NET Framework System. URI classe, e esse é o tipo a ser usado para o parâmetro do método.The equivalent type in managed code is the .NET Framework System.Uri class, and that's the type to use for the method parameter. É possível dizer quando um tipo do Windows Runtime é exibido como um tipo do .NET Framework, porque o IntelliSense no Visual Studio oculta o tipo do Windows Runtime quando você está escrevendo código gerenciado e apresenta o tipo .NET Framework equivalente.You can tell when a Windows Runtime type appears as a .NET Framework type, because IntelliSense in Visual Studio hides the Windows Runtime type when you're writing managed code, and presents the equivalent .NET Framework type. (Normalmente, os dois tipos têm o mesmo nome.(Usually the two types have the same name. No entanto, observe que o Windows.Foundation.DateTime estrutura aparece no código gerenciado como System. DateTimeOffset e não como System. DateTime.)However, note that the Windows.Foundation.DateTime structure appears in managed code as System.DateTimeOffset and not as System.DateTime.)

Para alguns tipos de coleção mais usados, o mapeamento é entre as interfaces implementadas por um tipo do Windows Runtime e as interfaces implementadas pelo tipo .NET Framework correspondente.For some commonly used collection types, the mapping is between the interfaces that are implemented by a Windows Runtime type and the interfaces that are implemented by the corresponding .NET Framework type. Assim como acontece com os tipos mencionados acima, você declara tipos de parâmetro usando o tipo .NET Framework.As with the types mentioned above, you declare parameter types by using the .NET Framework type. Isso oculta algumas diferenças entre os tipos e deixa a escrita do código .NET Framework mais natural.This hides some differences between the types and makes writing .NET Framework code more natural.

A tabela a seguir lista os tipos de interface genérica mais comuns, além de outros mapeamentos de classe e interface comuns.The following table lists the most common of these generic interface types, along with other common class and interface mappings. Para obter uma lista completa dos tipos de tempo de execução do Windows que o .NET Framework mapeia, consulte mapeamentos do .NET Framework de tipos do Windows Runtime.For a complete list of Windows Runtime types that the .NET Framework maps, see .NET Framework mappings of Windows Runtime types.

Tempo de execução do WindowsWindows Runtime .NET Framework.NET Framework
IIterable<T>IIterable<T> IEnumerable<T>IEnumerable<T>
IVector<T>IVector<T> IList<T>IList<T>
IVectorView<T>IVectorView<T> IReadOnlyList<T>IReadOnlyList<T>
IMap<K, V>IMap<K, V> IDictionary<TKey, TValue>IDictionary<TKey, TValue>
IMapView<K, V>IMapView<K, V> IReadOnlyDictionary<TKey, TValue>IReadOnlyDictionary<TKey, TValue>
IKeyValuePair<K, V>IKeyValuePair<K, V> KeyValuePair<TKey, TValue>KeyValuePair<TKey, TValue>
IBindableIterableIBindableIterable IEnumerableIEnumerable
IBindableVectorIBindableVector IListIList
Windows.UI.Xaml.Data.INotifyPropertyChangedWindows.UI.Xaml.Data.INotifyPropertyChanged System.ComponentModel.INotifyPropertyChangedSystem.ComponentModel.INotifyPropertyChanged
Windows.UI.Xaml.Data.PropertyChangedEventHandlerWindows.UI.Xaml.Data.PropertyChangedEventHandler System.ComponentModel.PropertyChangedEventHandlerSystem.ComponentModel.PropertyChangedEventHandler
Windows.UI.Xaml.Data.PropertyChangedEventArgsWindows.UI.Xaml.Data.PropertyChangedEventArgs System.ComponentModel.PropertyChangedEventArgsSystem.ComponentModel.PropertyChangedEventArgs

Quando um tipo implementa mais de uma interface, é possível usar qualquer uma das interfaces implementadas como um tipo de parâmetro ou um tipo de retorno de um membro.When a type implements more than one interface, you can use any of the interfaces it implements as a parameter type or return type of a member. Por exemplo, você pode transmitir ou retornar um dicionário<int, cadeia de caracteres> (Dictionary (Of Integer, String) no Visual Basic) como IDictionary<int, cadeia de caracteres> , IReadOnlyDictionary<int, string> , ou IEnumerable< System.Collections.Generic.KeyValuePair<TKey, TValue>> .For example, you can pass or return a Dictionary<int, string> (Dictionary(Of Integer, String) in Visual Basic) as IDictionary<int, string>, IReadOnlyDictionary<int, string>, or IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>.

Importante

O JavaScript usa a interface que aparece primeira na lista de interfaces implementadas por um tipo gerenciado.JavaScript uses the interface that appears first in the list of interfaces that a managed type implements. Por exemplo, se você retornar dicionário<int, cadeia de caracteres> para o código JavaScript, ele aparece como IDictionary<int, string> , não importa qual interface que você especificar como o tipo de retorno.For example, if you return Dictionary<int, string> to JavaScript code, it appears as IDictionary<int, string> no matter which interface you specify as the return type. Isso significa que, se a primeira interface não incluir um membro exibido em interfaces posteriores, esse membro não permanecerá visível para JavaScript.This means that if the first interface doesn't include a member that appears on later interfaces, that member isn't visible to JavaScript.

No tempo de execução Windows IMap<K, V> e IMapView<K, V> são iterados usando 1>{2>Platform::Collections::inputiterator<ikeyvaluepair<k.In the Windows Runtime, IMap<K, V> and IMapView<K, V> are iterated by using IKeyValuePair. Quando você os transmite para código gerenciado, eles aparecem como IDictionary<TKey, TValue> e IReadOnlyDictionary<TKey, TValue> , portanto, Naturalmente, você usa System.Collections.Generic.KeyValuePair<TKey, TValue> para enumerá-los.When you pass them to managed code, they appear as IDictionary<TKey, TValue> and IReadOnlyDictionary<TKey, TValue>, so naturally you use System.Collections.Generic.KeyValuePair<TKey, TValue> to enumerate them.

A maneira como as interfaces são exibidas em código gerenciado afeta o modo como os tipos que implementam essas interfaces são exibidos.The way interfaces appear in managed code affects the way types that implement these interfaces appear. Por exemplo, o PropertySet classe implementa IMap<K, V> , que aparece no código gerenciado como IDictionary<TKey, TValue> .For example, the PropertySet class implements IMap<K, V>, which appears in managed code as IDictionary<TKey, TValue>. PropertySet aparece como se tivesse implementado IDictionary<TKey, TValue> em vez de IMap<K, V> , em gerenciado código que ele parece ter um Add método, que se comporta como o Add método nos dicionários do .NET Framework.PropertySet appears as if it implemented IDictionary<TKey, TValue> instead of IMap<K, V>, so in managed code it appears to have an Add method, which behaves like the Add method on .NET Framework dictionaries. Ele não parece ter um inserir método.It doesn't appear to have an Insert method. Você pode ver esse exemplo no tópico passo a passo: Criando um componente simples em C# ou Visual Basic e chamando-o por JavaScript.You can see this example in the topic Walkthrough: Creating a simple component in C# or Visual Basic and calling it from JavaScript.

Passagem de tipos gerenciados para o Windows RuntimePassing managed types to the Windows Runtime

Conforme abordado na seção anterior, alguns tipos do Windows Runtime podem ser exibidos como tipos do .NET Framework nas assinaturas dos membros do componente ou nas assinaturas dos membros do Windows Runtime quando você os usa no IDE.As discussed in the previous section, some Windows Runtime types can appear as .NET Framework types in the signatures of your component's members, or in the signatures of Windows Runtime members when you use them in the IDE. Quando você passa tipos do .NET Framework para esses membros ou os usa como os valores de retorno dos membros do componente, eles são exibidos no código do outro lado como o tipo do Windows Runtime correspondente.When you pass .NET Framework types to these members or use them as the return values of your component's members, they appear to the code on the other side as the corresponding Windows Runtime type. Para obter exemplos dos efeitos que isso pode ter quando seu componente é chamado do JavaScript, consulte a seção "Retornando tipos gerenciados de seu componente" em passo a passo: Criando um componente simples em C# ou Visual Basic e chamando-o por JavaScript.For examples of the effects this can have when your component is called from JavaScript, see the "Returning managed types from your component" section in Walkthrough: Creating a simple component in C# or Visual Basic and calling it from JavaScript.

Métodos sobrecarregadosOverloaded methods

No Windows Runtime, os métodos podem ser sobrecarregados.In the Windows Runtime, methods can be overloaded. No entanto, se você declarar várias sobrecargas com o mesmo número de parâmetros, você deve aplicar a defaultoverloadattribute de atributo a apenas uma dessas sobrecargas.However, if you declare multiple overloads with the same number of parameters, you must apply the Windows.Foundation.Metadata.DefaultOverloadAttribute attribute to only one of those overloads. Essa sobrecarga é a única que é possível chamar no JavaScript.That overload is the only one you can call from JavaScript. Por exemplo, no código a seguir, a sobrecarga que utiliza um int (Integer em Visual Basic) é a sobrecarga padrão.For example, in the following code the overload that takes an int (Integer in Visual Basic) is the default overload.

public string OverloadExample(string s)
{
    return s;
}

[Windows.Foundation.Metadata.DefaultOverload()]
public int OverloadExample(int x)
{
    return x;
}
Public Function OverloadExample(ByVal s As String) As String
    Return s
End Function

<Windows.Foundation.Metadata.DefaultOverload> _
Public Function OverloadExample(ByVal x As Integer) As Integer
    Return x
End Function

[IMPORTANTE] JavaScript permite que você transmita qualquer valor para OverloadExamplee força o valor para o tipo que é exigido pelo parâmetro.[IMPORTANT] JavaScript allows you to pass any value to OverloadExample, and coerces the value to the type that is required by the parameter. Você pode chamar OverloadExample com "quarenta e dois", "42" ou 42.3, mas todos esses valores são passados para a sobrecarga padrão.You can call OverloadExample with "forty-two", "42", or 42.3, but all those values are passed to the default overload. A sobrecarga padrão no exemplo anterior retorna 0, 42 e 42, respectivamente.The default overload in the previous example returns 0, 42, and 42, respectively.

Não é possível aplicar a DefaultOverloadAttributatributo e para construtores.You can't apply the DefaultOverloadAttribute attribute to constructors. Todos os construtores em uma classe devem ter números de parâmetros diferentes.All the constructors in a class must have different numbers of parameters.

Implementação de IStringableImplementing IStringable

Começando com o Windows 8.1, o tempo de execução do Windows inclui um IStringable cujo único método, da interface Istringable, fornece suporte para formatação básica comparado ao que é fornecido pelo ToString.Starting with Windows 8.1, the Windows Runtime includes an IStringable interface whose single method, IStringable.ToString, provides basic formatting support comparable to that provided by Object.ToString. Se você optar por implementar IStringable em um tipo gerenciado público exportado em um componente de tempo de execução do Windows, as seguintes restrições se aplicam:If you do choose to implement IStringable in a public managed type that is exported in a Windows Runtime component, the following restrictions apply:

  • Você pode definir as IStringable interface somente em uma relação de "implementos de classe", como o seguinte código no C#:You can define the IStringable interface only in a "class implements" relationship, such as the following code in C#:

    public class NewClass : IStringable
    

    Ou o seguinte código do Visual Basic:Or the following Visual Basic code:

    Public Class NewClass : Implements IStringable
    
  • Você não pode implementar IStringable em uma interface.You can't implement IStringable on an interface.

  • Você não pode declarar um parâmetro seja do tipo IStringable.You can't declare a parameter to be of type IStringable.

  • IStringable não pode ser o tipo de retorno de método, propriedade ou campo.IStringable can't be the return type of a method, property, or field.

  • Você não pode ocultar sua IStringable implementação de classes base usando uma definição de método como o seguinte:You can't hide your IStringable implementation from base classes by using a method definition such as the following:

    public class NewClass : IStringable
    {
       public new string ToString()
       {
          return "New ToString in NewClass";
       }
    }
    

    Em vez disso, o Istringable implementação sempre deve substituir a implementação da classe base.Instead, the IStringable.ToString implementation must always override the base class implementation. Você pode ocultar uma ToString implementação apenas invocando-a em uma instância da classe fortemente tipada.You can hide a ToString implementation only by invoking it on a strongly typed class instance.

Observação

Em uma variedade de condições, chamadas de código nativo para um tipo gerenciado que implementa IStringable ou oculta sua ToString implementação pode produzir um comportamento inesperado.Under a variety of conditions, calls from native code to a managed type that implements IStringable or hides its ToString implementation can produce unexpected behavior.

Operações assíncronasAsynchronous operations

Para implementar um método assíncrono em seu componente, adicione "Async" ao final do nome do método e retorne uma das interfaces de tempo de execução do Windows que representam ações ou operações assíncronas: IAsyncAction, IAsyncActionWithProgress<TProgress> , IAsyncOperation<TResult> , ou IAsyncOperationWithProgress<TResult, TProgress> .To implement an asynchronous method in your component, add "Async" to the end of the method name and return one of the Windows Runtime interfaces that represent asynchronous actions or operations: IAsyncAction, IAsyncActionWithProgress<TProgress>, IAsyncOperation<TResult>, or IAsyncOperationWithProgress<TResult, TProgress>.

Você pode usar tarefas do .NET Framework (a tarefa classe e genérico tarefa<TResult> classe) para Implemente o método assíncrono.You can use .NET Framework tasks (the Task class and generic Task<TResult> class) to implement your asynchronous method. Você deve retornar uma tarefa que representa uma operação contínua, como uma tarefa que é retornada de um método assíncrono gravado C# ou Visual Basic, ou uma tarefa que é retornada de Task. Run método.You must return a task that represents an ongoing operation, such as a task that is returned from an asynchronous method written in C# or Visual Basic, or a task that is returned from the Task.Run method. Caso use um construtor para criar a tarefa, você deve chamar o método Task.Start antes de devolvê-lo.If you use a constructor to create the task, you must call its Task.Start method before returning it.

Um método que usa await (Await no Visual Basic) requer o async palavra-chave (Async no Visual Basic).A method that uses await (Await in Visual Basic) requires the async keyword (Async in Visual Basic). Se você expuser esse método um de um componente de tempo de execução do Windows, se aplicam a async palavra-chave para o delegado que você passa para o executar método.If you expose such a method from a Windows Runtime component, apply the async keyword to the delegate that you pass to the Run method.

Para ações e operações assíncronas que não dão suporte ao cancelamento ou aos relatórios de progresso, é possível usar o método de extensão WindowsRuntimeSystemExtensions.AsAsyncAction ou AsAsyncOperation<TResult> para encapsular a tarefa na interface apropriada.For asynchronous actions and operations that do not support cancellation or progress reporting, you can use the WindowsRuntimeSystemExtensions.AsAsyncAction or AsAsyncOperation<TResult> extension method to wrap the task in the appropriate interface. Por exemplo, o código a seguir implementa um método assíncrono usando o Task. Run<TResult> método para iniciar uma tarefa.For example, the following code implements an asynchronous method by using the Task.Run<TResult> method to start a task. O AsAsyncOperation<TResult> método de extensão retorna a tarefa como uma operação assíncrona de tempo de execução do Windows.The AsAsyncOperation<TResult> extension method returns the task as a Windows Runtime asynchronous operation.

public static IAsyncOperation<IList<string>> DownloadAsStringsAsync(string id)
{
    return Task.Run<IList<string>>(async () =>
    {
        var data = await DownloadDataAsync(id);
        return ExtractStrings(data);
    }).AsAsyncOperation();
}
Public Shared Function DownloadAsStringsAsync(ByVal id As String) _
     As IAsyncOperation(Of IList(Of String))

    Return Task.Run(Of IList(Of String))(
        Async Function()
            Dim data = Await DownloadDataAsync(id)
            Return ExtractStrings(data)
        End Function).AsAsyncOperation()
End Function

O código JavaScript a seguir mostra como o método poderia ser chamado usando um WinJS. Promise objeto.The following JavaScript code shows how the method could be called by using a WinJS.Promise object. A função passada para o método then é executada quando a chamada assíncrona é concluída.The function that is passed to the then method is executed when the asynchronous call completes. O parâmetro stringList contém a lista de cadeias de caracteres que é retornado pelo DownloadAsStringAsync método e a função executa o processamento que for necessário.The stringList parameter contains the list of strings that is returned by the DownloadAsStringAsync method, and the function does whatever processing is required.

function asyncExample(id) {

    var result = SampleComponent.Example.downloadAsStringAsync(id).then(
        function (stringList) {
            // Place code that uses the returned list of strings here.
        });
}

Para ações e operações assíncronas que oferecem suporte ao cancelamento ou relatório de andamento, use o AsyncInfo classe para gerar uma tarefa iniciada e para conectar o cancelamento e relatório de andamento recursos da tarefa com o cancelamento e recursos da interface do Windows Runtime apropriada do relatório de andamento.For asynchronous actions and operations that support cancellation or progress reporting, use the AsyncInfo class to generate a started task and to hook up the cancellation and progress reporting features of the task with the cancellation and progress reporting features of the appropriate Windows Runtime interface. Para obter um exemplo que oferece suporte ao cancelamento e o relatório de progresso, consulte passo a passo: Criando um componente simples em C# ou Visual Basic e chamando-o por JavaScript.For an example that supports both cancellation and progress reporting, see Walkthrough: Creating a simple component in C# or Visual Basic and calling it from JavaScript.

Observe que você pode usar os métodos do AsyncInfo classe mesmo se seu método assíncrono não oferecer suporte ao cancelamento ou relatório de progresso.Note that you can use the methods of the AsyncInfo class even if your asynchronous method doesn't support cancellation or progress reporting. Se você usar uma função lambda Visual Basic ou um C# método anônimo, não forneça parâmetros para o token e IProgress<T> interface.If you use a Visual Basic lambda function or a C# anonymous method, don't supply parameters for the token and IProgress<T> interface. Caso você use uma função lambda de C#, forneça um parâmetro token, mas o ignore.If you use a C# lambda function, supply a token parameter but ignore it. O exemplo anterior, o que é usado o AsAsyncOperation<TResult> método, se parece com isso, quando você usa o AsyncInfo.Run<TResult>(Func< CancellationToken, tarefa<TResult>> ) em vez disso, a sobrecarga de método.The previous example, which used the AsAsyncOperation<TResult> method, looks like this when you use the AsyncInfo.Run<TResult>(Func<CancellationToken, Task<TResult>>) method overload instead.

public static IAsyncOperation<IList<string>> DownloadAsStringsAsync(string id)
{
    return AsyncInfo.Run<IList<string>>(async (token) =>
    {
        var data = await DownloadDataAsync(id);
        return ExtractStrings(data);
    });
}
Public Shared Function DownloadAsStringsAsync(ByVal id As String) _
    As IAsyncOperation(Of IList(Of String))

    Return AsyncInfo.Run(Of IList(Of String))(
        Async Function()
            Dim data = Await DownloadDataAsync(id)
            Return ExtractStrings(data)
        End Function)
End Function

Se você criar um método assíncrono que ofereça suporte opcionalmente a relatórios de cancelamento ou progresso, considere adicionar as sobrecargas que não tenham parâmetros para um token de cancelamento ou a IProgress<T> interface.If you create an asynchronous method that optionally supports cancellation or progress reporting, consider adding overloads that don't have parameters for a cancellation token or the IProgress<T> interface.

Acionamento de exceçõesThrowing exceptions

É possível acionar qualquer tipo de exceção que esteja incluído no .NET para aplicativos do Windows.You can throw any exception type that is included in the .NET for Windows apps. Não é possível declarar os próprios tipos de exceção pública em um componente do Tempo de Execução do Windows, mas você pode declarar e acionar tipos não públicos.You can't declare your own public exception types in a Windows Runtime component, but you can declare and throw non-public types.

Caso o componente não manipule a exceção, uma exceção correspondente é acionada no código que chamou o componente.If your component doesn't handle the exception, a corresponding exception is raised in the code that called your component. A maneira como a exceção é exibida para o chamador depende da maneira como a linguagem de chamada dá suporte ao Windows Runtime.The way the exception appears to the caller depends on the way the calling language supports the Windows Runtime.

  • Em JavaScript, a exceção é exibida como um objeto no qual a mensagem de exceção é substituída por um rastreamento de pilha.In JavaScript, the exception appears as an object in which the exception message is replaced by a stack trace. Ao depurar o aplicativo no Visual Studio, você pode ver o texto da mensagem original exibido na caixa de diálogo de exceção do depurador, identificado como "Informações de WinRT".When you debug your app in Visual Studio, you can see the original message text displayed in the debugger exception dialog box, identified as "WinRT Information". Não é possível acessar o texto da mensagem original no código JavaScript.You can't access the original message text from JavaScript code.

    Dica.Tip. Atualmente, o rastreamento de pilha contém o tipo de exceção gerenciada, mas não é recomendável analisar o rastreamento para identificar o tipo de exceção. Currently, the stack trace contains the managed exception type, but we don't recommend parsing the trace to identify the exception type. Em vez disso, use um valor HRESULT conforme descrito mais à frente nesta seção.Instead, use an HRESULT value as described later in this section.

  • Em C++, a exceção é exibida como uma exceção da plataforma.In C++, the exception appears as a platform exception. Se a propriedade de HResult da exceção gerenciada pode ser mapeada para o HRESULT de uma exceção de plataforma específica, a exceção específica é usada; Caso contrário, uma Platform:: COMException exceção é lançada.If the managed exception's HResult property can be mapped to the HRESULT of a specific platform exception, the specific exception is used; otherwise, a Platform::COMException exception is thrown. O texto da mensagem da exceção gerenciada não está disponível para o código C++.The message text of the managed exception is not available to C++ code. Caso uma exceção de plataforma específica seja acionada, o texto da mensagem padrão desse tipo de exceção é exibido; do contrário, nenhum texto de mensagem é exibido.If a specific platform exception was thrown, the default message text for that exception type appears; otherwise, no message text appears. Consulte Exceções (C++/CX).See Exceptions (C++/CX).

  • Em C# ou Visual Basic, a exceção é uma exceção gerenciada normal.In C# or Visual Basic, the exception is a normal managed exception.

Ao acionar uma exceção no componente, você pode facilitar para um chamador JavaScript ou C++ lidar com a exceção acionando um tipo de exceção não público cujo valor da propriedade HResult é específico do componente.When you throw an exception from your component, you can make it easier for a JavaScript or C++ caller to handle the exception by throwing a non-public exception type whose HResult property value is specific to your component. O HRESULT está disponível para um chamador JavaScript por meio da propriedade de número do objeto de exceção e para um chamador C++, por meio de COMException:: HRESULT propriedade.The HRESULT is available to a JavaScript caller through the exception object's number property, and to a C++ caller through the COMException::HResult property.

Observação

Use um valor negativo para o HRESULT.Use a negative value for your HRESULT. Um valor positivo é interpretado como êxito, e nenhuma exceção é acionada no chamador JavaScript ou C++.A positive value is interpreted as success, and no exception is thrown in the JavaScript or C++ caller.

Declaração e acionamento de eventosDeclaring and raising events

Quando você declara um tipo para manter os dados do evento, derive de Object, em vez de EventArgs, porque EventArgs não é um tipo do Windows Runtime.When you declare a type to hold the data for your event, derive from Object instead of from EventArgs, because EventArgs is not a Windows Runtime type. Use EventHandler<TEventArgs> como o tipo de evento e use o tipo de seu argumento de evento como o argumento de tipo genérico.Use EventHandler<TEventArgs> as the type of the event, and use your event argument type as the generic type argument. Acione o evento, assim como você faria em um aplicativo do .NET Framework.Raise the event just as you would in a .NET Framework application.

Quando o componente do Tempo de Execução do Windows é usado em JavaScript ou C++, o evento segue o padrão de evento do Windows Runtime que essas linguagens esperam.When your Windows Runtime component is used from JavaScript or C++, the event follows the Windows Runtime event pattern that those languages expect. Quando você usa o componente de C# ou Visual Basic, o evento é exibido como um evento do .NET Framework comum.When you use the component from C# or Visual Basic, the event appears as an ordinary .NET Framework event. Um exemplo é fornecido no passo a passo: Criando um componente simples em C# ou Visual Basic e chamando-o por JavaScript.An example is provided in Walkthrough: Creating a simple component in C# or Visual Basic and calling it from JavaScript.

Caso implemente acessadores de eventos personalizado (declarar um evento com a palavra-chave Custom, em Visual Basic), você deve seguir o padrão de evento do Windows Runtime na implementação.If you implement custom event accessors (declare an event with the Custom keyword, in Visual Basic), you must follow the Windows Runtime event pattern in your implementation. Consulte Eventos personalizados e acessadores de evento em componentes do Tempo de Execução do Windows.See Custom events and event accessors in Windows Runtime Components. Quando você manipula o evento no código C# ou Visual Basic, ele ainda parece ser um evento do .NET Framework comum.Note that when you handle the event from C# or Visual Basic code, it still appears to be an ordinary .NET Framework event.

Próximas etapasNext steps

Depois que tiver criado um componente do Tempo de Execução do Windows para o próprio uso, talvez você ache que a funcionalidade que ele encapsula é útil para outros desenvolvedores.After you’ve created a Windows Runtime component for your own use, you may find that the functionality it encapsulates is useful to other developers. Você tem duas opções para empacotar um componente para distribuição a outros desenvolvedores.You have two options for packaging a component for distribution to other developers. Consulte Distribuição de um componente do Tempo de Execução do Windows gerenciado.See Distributing a managed Windows Runtime component.

Para saber mais sobre recursos da linguagem Visual Basic e C# e o suporte do .NET Framework ao Windows Runtime, consulte a Referência das linguagens Visual Basic e C#.For more information about Visual Basic and C# language features, and .NET Framework support for the Windows Runtime, see Visual Basic and C# language reference.