Componenti Windows Runtime con C# e Visual BasicWindows Runtime components with C# and Visual Basic

È possibile utilizzare il codice gestito per creare tipi di Windows Runtime personalizzati e comprimerli in un componente di Windows Runtime.You can use managed code to create your own Windows Runtime types and package them in a Windows Runtime component. È possibile usare il componente nelle app piattaforma UWP (Universal Windows Platform) (UWP) scritte in C++, JavaScript, Visual Basic o C#.You can use your component in Universal Windows Platform (UWP) apps that are written in C++, JavaScript, Visual Basic, or C#. Questo argomento descrive le regole per la creazione di un componente e illustra alcuni aspetti del supporto di .NET per Windows Runtime.This topic outlines the rules for creating a component, and discusses some aspects of .NET support for the Windows Runtime. In generale, questo supporto è progettato per essere trasparente per il programmatore .NET.In general, that support is designed to be transparent to the .NET programmer. Tuttavia, quando crei un componente da usare con JavaScript o C++, devi tenere presenti le differenze nella modalità di supporto di Windows Runtime in questi linguaggi.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 si sta creando un componente da usare solo nelle app UWP scritte in Visual Basic o C# e il componente non contiene controlli UWP, provare a usare il modello di libreria di classi anziché il modello di progetto componente di Windows Runtime in 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 consider using the Class Library template instead of the Windows Runtime Component project template in Microsoft Visual Studio. Una libreria di classi semplice prevede meno restrizioni.There are fewer restrictions on a simple class library.

Dichiarazione di tipi in componenti Windows RuntimeDeclaring types in Windows Runtime components

Internamente, i tipi di Windows Runtime nel componente possono usare qualsiasi funzionalità .NET consentita in un'app UWP.Internally, the Windows Runtime types in your component can use any .NET functionality that's allowed in a UWP app. Per altre informazioni, vedere .NET per le app UWP.For more info, see .NET for UWP apps.

Esternamente, i membri dei tipi possono esporre solo Windows Runtime tipi per i relativi parametri e valori restituiti.Externally, the members of your types can expose only Windows Runtime types for their parameters and return values. Nell'elenco seguente vengono descritte le limitazioni relative ai tipi .NET esposti da un componente Windows Runtime.The following list describes the limitations on .NET types that are exposed from a Windows Runtime component.

  • I campi, i parametri e i valori restituiti di tutti i membri e i tipi pubblici nel componente devono essere tipi Windows Runtime.The fields, parameters, and return values of all the public types and members in your component must be Windows Runtime types. Questa restrizione include i tipi di Windows Runtime creati e i tipi forniti dal Windows Runtime stesso.This restriction includes the Windows Runtime types that you author as well as types that are provided by the Windows Runtime itself. Include anche una serie di tipi .NET.It also includes a number of .NET types. L'inclusione di questi tipi fa parte del supporto fornito da .NET per consentire l'utilizzo naturale del Windows Runtime nel codice gestito in — cui il codice sembra utilizzare tipi .NET noti anziché i tipi di Windows Runtime sottostanti.The inclusion of these types is part of the support that .NET provides to enable the natural use of the Windows Runtime in managed code—your code appears to use familiar .NET types instead of the underlying Windows Runtime types. Ad esempio, è possibile usare i tipi primitivi .NET, ad esempio Int32 e Double, determinati tipi fondamentali come DateTimeOffset e URIe alcuni tipi di interfaccia generici comunemente usati, ad esempio **ienumerable < T > ** (IEnumerable (Of T) in Visual Basic) e **IDictionary < TKey, TValue > **.For example, you can use .NET 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>. Si noti che gli argomenti tipo di questi tipi generici devono essere Windows Runtime tipi.Note that the type arguments of these generic types must be Windows Runtime types. Questa operazione viene illustrata nelle sezioni passaggio Windows Runtime tipi al codice gestito e passaggio di tipi gestiti alla Windows Runtime, più avanti in questo argomento.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.

  • Le interfacce e le classi pubbliche possono contenere metodi, proprietà ed eventi.Public classes and interfaces can contain methods, properties, and events. È possibile dichiarare delegati per gli eventi o utilizzare il delegato **EventHandler < T > ** .You can declare delegates for your events, or use the EventHandler<T> delegate. Una classe pubblica o un'interfaccia non può:A public class or interface can't:

    • Essere generica.Be generic.
    • Implementare un'interfaccia che non sia un'interfaccia Windows Runtime (Tuttavia, è possibile creare interfacce Windows Runtime personalizzate e implementarle).Implement an interface that is not a Windows Runtime interface (however, you can create your own Windows Runtime interfaces and implement them).
    • Derivare da tipi non inclusi nel Windows Runtime, ad esempio System. Exception e System. EventArgs.Derive from types that are not in the Windows Runtime, such as System.Exception and System.EventArgs.
  • Tutti i tipi pubblici devono avere uno spazio dei nomi radice corrispondente al nome dell'assembly e il nome dell'assembly non deve iniziare con "Windows".All public types must have a root namespace that matches the assembly name, and the assembly name must not begin with "Windows".

    Suggerimento.Tip. Per impostazione predefinita, i progetti di Visual Studio hanno nomi dello spazio dei nomi corrispondenti al nome dell'assembly.By default, Visual Studio projects have namespace names that match the assembly name. In Visual Basic l'istruzione Namespace per questo spazio dei nomi predefinito non è visualizzata nel codice.In Visual Basic, the Namespace statement for this default namespace is not shown in your code.

  • Le strutture pubbliche non possono contenere membri diversi dai campi pubblici e questi campi devono essere stringhe o tipi di valore.Public structures can't have any members other than public fields, and those fields must be value types or strings.

  • Le classi pubbliche devono essere sealed (NotInheritable in Visual Basic).Public classes must be sealed (NotInheritable in Visual Basic). Se il modello di programmazione richiede il polimorfismo, è possibile creare un'interfaccia pubblica e implementare tale interfaccia sulle classi che devono essere polimorfiche.If your programming model requires polymorphism, then you can create a public interface, and implement that interface on the classes that must be polymorphic.

Debug del componenteDebugging your component

Se sia l'app UWP che il componente sono compilati con codice gestito, è possibile eseguirne il debug contemporaneamente.If both your UWP app and your component are built with managed code, then you can debug them both at the same time.

Quando si esegue il test del componente come parte di un'app UWP con C++, è possibile eseguire il debug di codice gestito e nativo nello stesso momento.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. Per impostazione predefinita viene eseguito il debug del solo codice nativo.The default is native code only.

Per eseguire il debug sia del codice C++ nativo sia del codice gestitoTo debug both native C++ code and managed code

  1. Apri il menu di scelta rapida relativo al progetto Visual C++ e scegli Proprietà.Open the shortcut menu for your Visual C++ project, and choose Properties.
  2. Nella pagina delle proprietà, in Proprietà di configurazione, scegli Debug.In the property pages, under Configuration Properties, choose Debugging.
  3. Scegli Tipo di debugger e nell'elenco a discesa modifica Solo nativo in Misto (gestito e nativo).Choose Debugger Type, and in the drop-down list box change Native Only to Mixed (Managed and Native). Scegliere OK.Choose OK.
  4. Imposta i punti di interruzione nel codice nativo e in quello gestito.Set breakpoints in native and managed code.

Quando si sta testando il componente come parte di un'app UWP usando JavaScript, per impostazione predefinita la soluzione è in modalità di debug JavaScript.When you're testing your component as part of a UWP app using JavaScript, by default the solution is in JavaScript debugging mode. In Visual Studio non puoi eseguire il debug di JavaScript e del codice gestito contemporaneamente.In Visual Studio, you can't debug JavaScript and managed code at the same time.

Per eseguire il debug del codice gestito invece che di JavaScriptTo debug managed code instead of JavaScript

  1. Apri il menu di scelta rapida relativo al progetto JavaScript e scegli Proprietà.Open the shortcut menu for your JavaScript project, and choose Properties.
  2. Nella pagina delle proprietà, in Proprietà di configurazione, scegli Debug.In the property pages, under Configuration Properties, choose Debugging.
  3. Scegli Tipo di debugger e nell'elenco a discesa modifica Solo script in Solo gestito.Choose Debugger Type, and in the drop-down list box change Script Only to Managed Only. Scegliere OK.Choose OK.
  4. Imposta i punti di interruzione nel codice gestito ed esegui normalmente il debug.Set breakpoints in managed code and debug as usual.

Passaggio di tipi Windows Runtime al codice gestitoPassing Windows Runtime types to managed code

Come indicato in precedenza nella sezione dichiarazione di tipi in Windows Runtime componenti, alcuni tipi .NET possono apparire nelle firme dei membri delle classi pubbliche.As mentioned previously in the section Declaring types in Windows Runtime components, certain .NET types can appear in the signatures of members of public classes. Questo è parte del supporto fornito da .NET per consentire l'utilizzo naturale del Windows Runtime nel codice gestito.This is part of the support that .NET provides to enable the natural use of the Windows Runtime in managed code. Include i tipi primitivi e alcune classi e interfacce.It includes primitive types and some classes and interfaces. Quando il componente viene usato da JavaScript o dal codice C++, è importante comprendere come vengono visualizzati i tipi .NET al chiamante.When your component is used from JavaScript, or from C++ code, it's important to know how your .NET types appear to the caller. Per esempi con JavaScript , vedere la procedura dettagliata per la creazione di un componente Windows Runtime C# o Visual Basic e la chiamata da JavaScript .See Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript for examples with JavaScript. Questa sezione illustra i tipi di uso comune.This section discusses commonly used types.

In .NET i tipi primitivi, ad esempio la struttura Int32 , presentano molti metodi e proprietà utili, ad esempio il metodo TryParse .In .NET, primitive types such as the Int32 structure have many useful properties and methods, such as the TryParse method. Al contrario, le strutture e i tipi primitivi in Windows Runtime hanno solo campi.By contrast, primitive types and structures in the Windows Runtime only have fields. Quando si passano questi tipi al codice gestito, sembrano essere tipi .NET ed è possibile utilizzare le proprietà e i metodi dei tipi .NET normalmente.When you pass these types to managed code, they appear to be .NET types, and you can use the properties and methods of .NET types as you normally would. L'elenco seguente riepiloga le sostituzioni effettuate automaticamente nell'IDE:The following list summarizes the substitutions that are made automatically in the IDE:

  • Per le primitive Windows Runtime Int32, Int64, Single, Double, Boolean, String (una raccolta non modificabile di caratteri Unicode), enum, UInt32, UInt64e GUID, usare il tipo con lo stesso nome nello spazio dei nomi 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.
  • Per Uint8, usare System. byte.For UInt8, use System.Byte.
  • Per Char16, usare System. Char.For Char16, use System.Char.
  • Per l'interfaccia IInspectable , usare System. Object.For the IInspectable interface, use System.Object.

Se C# o Visual Basic fornisce una parola chiave del linguaggio per uno di questi tipi, è possibile usare invece la parola chiave del linguaggio.If C# or Visual Basic provides a language keyword for any of these types, then you can use the language keyword instead.

Oltre ai tipi primitivi, alcuni tipi di Windows Runtime di base usati comunemente vengono visualizzati nel codice gestito come equivalenti di .NET.In addition to primitive types, some basic, commonly used Windows Runtime types appear in managed code as their .NET equivalents. Si supponga, ad esempio, che il codice JavaScript usi la classe Windows. Foundation. Uri e che lo si voglia passare a un metodo C# o 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. Il tipo equivalente nel codice gestito è la classe .NET System. Uri ed è il tipo da usare per il parametro del metodo.The equivalent type in managed code is the .NET System.Uri class, and that's the type to use for the method parameter. È possibile stabilire quando un tipo di Windows Runtime viene visualizzato come tipo .NET, perché IntelliSense in Visual Studio nasconde il tipo di Windows Runtime quando si scrive codice gestito e presenta il tipo .NET equivalente.You can tell when a Windows Runtime type appears as a .NET type, because IntelliSense in Visual Studio hides the Windows Runtime type when you're writing managed code, and presents the equivalent .NET type. In genere i due tipi hanno lo stesso nome.(Usually the two types have the same name. Si noti tuttavia che la struttura Windows. Foundation. DateTime viene visualizzata nel codice gestito come System. DateTimeOffset e non come System. DateTime.However, note that the Windows.Foundation.DateTime structure appears in managed code as System.DateTimeOffset and not as System.DateTime.)

Per alcuni tipi di raccolta comunemente utilizzati, il mapping è tra le interfacce implementate da un tipo di Windows Runtime e le interfacce implementate dal tipo .NET corrispondente.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 type. Come per i tipi indicati in precedenza, si dichiarano i tipi di parametro usando il tipo .NET.As with the types mentioned above, you declare parameter types by using the .NET type. Questo consente di nascondere alcune differenze tra i tipi e rende più naturale la scrittura di codice .NET.This hides some differences between the types and makes writing .NET code more natural.

La tabella seguente elenca i più comuni tra questi tipi di interfaccia generici, con altri mapping di interfacce e classi comuni.The following table lists the most common of these generic interface types, along with other common class and interface mappings. Per un elenco completo dei tipi di Windows Runtime di cui viene eseguito il mapping di .NET, vedere mapping .NET di tipi di Windows Runtime.For a complete list of Windows Runtime types that .NET maps, see .NET mappings of Windows Runtime types.

Windows RuntimeWindows Runtime .NET.NET
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 un tipo implementa più di un'interfaccia, puoi usare una qualsiasi delle interfacce implementate come tipo di parametro o tipo restituito di un 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. Ad esempio, è possibile passare o restituire un **dizionario < int, String > ** (**Dictionary (Of Integer, String)** in Visual Basic) come **IDictionary < int, String > **, **IReadOnlyDictionary < int, String > **o **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

JavaScript usa l'interfaccia visualizzata per prima nell'elenco di interfacce implementate da un tipo gestito.JavaScript uses the interface that appears first in the list of interfaces that a managed type implements. Se ad esempio si restituisce il **dizionario < int, stringa > ** al codice JavaScript, viene visualizzato come **IDictionary < int, stringa > ** indipendentemente dall'interfaccia specificata come tipo restituito.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. Questo significa che se la prima interfaccia non include un membro presente nelle interfacce successive, il membro non è visibile in 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.

Nel Windows Runtime, IMAP < k, > v e **IMapView < k, v > ** vengono iterati con IKeyValuePair.In the Windows Runtime, IMap<K, V> and IMapView<K, V> are iterated by using IKeyValuePair. Quando vengono passati al codice gestito, vengono visualizzati come **IDictionary < TKey, TValue > ** e **IReadOnlyDictionary < TKey, TValue > **, quindi naturalmente si usa **System. Collections. Generic. KeyValuePair < TKey, TValue > ** per enumerarli.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.

Il modo in cui le interfacce vengono visualizzate nel codice gestito influisce sul modo in cui vengono visualizzati i tipi tramite cui vengono implementate queste interfacce.The way interfaces appear in managed code affects the way types that implement these interfaces appear. Ad esempio, la classe PropertySet implementa **IMAP < K, V > **, che viene visualizzato nel codice gestito come IDictionary < TKey, > TValue.For example, the PropertySet class implements IMap<K, V>, which appears in managed code as IDictionary<TKey, TValue>. PropertySet viene visualizzato come se venisse implementato IDictionary < TKey, > TValue anziché **IMAP < K, V > **, quindi nel codice gestito sembra avere un metodo Add , che si comporta come il metodo Add nei dizionari .NET.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 dictionaries. Non sembra avere un metodo Insert .It doesn't appear to have an Insert method. È possibile vedere questo esempio nell'argomento procedura dettagliata per la creazione di un componente Windows Runtime C# o Visual Basic e la chiamata da JavaScript.You can see this example in the topic Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Passaggio di tipi gestiti a Windows RuntimePassing managed types to the Windows Runtime

Come illustrato nella sezione precedente, alcuni tipi di Windows Runtime possono apparire come tipi .NET nelle firme dei membri del componente o nelle firme dei membri Windows Runtime quando vengono usati nell'IDE.As discussed in the previous section, some Windows Runtime types can appear as .NET 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 si passano i tipi .NET a questi membri o li si usa come valori restituiti dei membri del componente, questi vengono visualizzati nel codice sull'altro lato come tipo di Windows Runtime corrispondente.When you pass .NET 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. Per esempi degli effetti che possono avere quando il componente viene chiamato da JavaScript, vedere la sezione "restituzione di tipi gestiti dal componente" in procedura dettagliata per la creazione di un componente di Windows Runtime C# o Visual Basic e la chiamata da 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 of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Metodi di overloadOverloaded methods

In Windows Runtime è possibile eseguire l'overload dei metodi.In the Windows Runtime, methods can be overloaded. Tuttavia, se si dichiarano più overload con lo stesso numero di parametri, è necessario applicare l'attributo Windows. Foundation. Metadata. DefaultOverloadAttribute solo a uno di questi overload.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. Tale overload è l'unico che puoi chiamare da JavaScript.That overload is the only one you can call from JavaScript. Nel codice seguente, ad esempio, l'overload che accetta int (Integer in Visual Basic) è l'overload predefinito.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 consente di passare qualsiasi valore a OverloadExamplee di assegnare il valore al tipo richiesto dal parametro.[IMPORTANT] JavaScript allows you to pass any value to OverloadExample, and coerces the value to the type that is required by the parameter. È possibile chiamare OverloadExample con "42", "42" o 42,3, ma tutti questi valori vengono passati all'overload predefinito.You can call OverloadExample with "forty-two", "42", or 42.3, but all those values are passed to the default overload. L'overload predefinito dell'esempio precedente restituisce rispettivamente 0, 42 e 42.The default overload in the previous example returns 0, 42, and 42, respectively.

Non è possibile applicare l'attributo DefaultOverloadAttribute ai costruttori.You can't apply the DefaultOverloadAttribute attribute to constructors. Tutti i costruttori di una classe devono avere numeri di parametri diversi.All the constructors in a class must have different numbers of parameters.

Implementazione di IStringableImplementing IStringable

A partire da Windows 8.1, il Windows Runtime include un'interfaccia di cui il singolo metodo, che è possibile ottenere . ToString, fornisce un supporto di formattazione di base analogo a quello fornito da Object. 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 si sceglie di implementare la pagina relativa all' implementazione di in un tipo gestito pubblico esportato in un componente Windows Runtime, si applicano le restrizioni seguenti:If you do choose to implement IStringable in a public managed type that is exported in a Windows Runtime component, the following restrictions apply:

  • È possibile definire l' interfaccia che può essere considerata solo in una relazione "classe Implements", ad esempio il codice seguente in C#:You can define the IStringable interface only in a "class implements" relationship, such as the following code in C#:

    public class NewClass : IStringable
    

    Oppure nel codice Visual Basic seguente:Or the following Visual Basic code:

    Public Class NewClass : Implements IStringable
    
  • Non è possibile implementare l' oggetto che è possibile implementare in un'interfaccia.You can't implement IStringable on an interface.

  • Non è possibile dichiarare un parametro di tipo.You can't declare a parameter to be of type IStringable.

  • Non può essere il tipo restituito di un metodo, di una proprietà o di un campo.IStringable can't be the return type of a method, property, or field.

  • Non è possibile nascondere l'implementazione di che può essere considerata dalle classi di base usando una definizione di metodo simile alla seguente: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";
       }
    }
    

    Al contrario, l'implementazione di . ToString è sempre necessario eseguire l'override dell'implementazione della classe di base.Instead, the IStringable.ToString implementation must always override the base class implementation. È possibile nascondere un'implementazione di ToString solo richiamandola su un'istanza di classe fortemente tipizzata.You can hide a ToString implementation only by invoking it on a strongly typed class instance.

Nota

In un'ampia gamma di condizioni, le chiamate dal codice nativo a un tipo gestito che implementa l' oggetto o che nasconde l'implementazione di ToString possono produrre un comportamento imprevisto.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.

Operazioni asincroneAsynchronous operations

Per implementare un metodo asincrono nel componente, aggiungere "Async" alla fine del nome del metodo e restituire una delle Windows Runtime interfacce che rappresentano azioni o operazioni asincrone: IAsyncAction, **IAsyncActionWithProgress < TProgress > **, **IAsyncOperation < TResult > **o **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>.

Per implementare il metodo asincrono, è possibile utilizzare le attività .NET, ovvero la classe di attività e la classe di attività generica ** < TResult > ** .You can use .NET tasks (the Task class and generic Task<TResult> class) to implement your asynchronous method. È necessario restituire un'attività che rappresenta un'operazione in corso, ad esempio un'attività restituita da un metodo asincrono scritto in C# o Visual Basic o un'attività restituita dal metodo Task. Run .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. Se usi un costruttore per creare l'attività, devi chiamare il relativo metodo Task.Start prima di restituirlo.If you use a constructor to create the task, you must call its Task.Start method before returning it.

Un metodo che usa await ( Await in Visual Basic) richiede la async parola chiave ( Async in Visual Basic).A method that uses await (Await in Visual Basic) requires the async keyword (Async in Visual Basic). Se si espone un metodo di questo tipo da un componente Windows Runtime, applicare la async parola chiave al delegato passato al metodo Run .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.

Per le operazioni e le azioni asincrone che non supportano l'annullamento o la segnalazione dello stato, puoi usare il metodo di estensione WindowsRuntimeSystemExtensions.AsAsyncAction o AsAsyncOperation<TResult> per eseguire il wrapping dell'attività nell'interfaccia appropriata.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. Il codice seguente, ad esempio, implementa un metodo asincrono usando il metodo Task. < Run > TResult per avviare un'attività.For example, the following code implements an asynchronous method by using the Task.Run<TResult> method to start a task. Il metodo di estensione **AsAsyncOperation < TResult > ** restituisce l'attività come Windows Runtime operazione asincrona.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

Il codice JavaScript seguente mostra come chiamare il metodo usando un oggetto WinJS. Promise .The following JavaScript code shows how the method could be called by using a WinJS.Promise object. La funzione passata al metodo then viene eseguita al completamento della chiamata asincrona.The function that is passed to the then method is executed when the asynchronous call completes. Il parametro String List contiene l'elenco di stringhe restituito dal metodo DownloadAsStringAsync e la funzione esegue qualsiasi operazione di elaborazione richiesta.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.
        });
}

Per le azioni e le operazioni asincrone che supportano la creazione di report sull'annullamento o sullo stato di avanzamento, utilizzare la classe AsyncInfo per generare un'attività avviata e associare le funzionalità di annullamento e segnalazione dello stato di avanzamento dell'attività con le funzionalità di segnalazione dell'annullamento e dello stato dell'interfaccia Windows Runtime appropriata.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. Per un esempio che supporta la creazione di report sull'annullamento e sullo stato di avanzamento, vedere procedura dettagliata per la creazione di un componente Windows Runtime C# o Visual Basic e la chiamata da JavaScript.For an example that supports both cancellation and progress reporting, see Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Si noti che è possibile usare i metodi della classe AsyncInfo anche se il metodo asincrono non supporta la creazione di report sull'annullamento o sullo stato di avanzamento.Note that you can use the methods of the AsyncInfo class even if your asynchronous method doesn't support cancellation or progress reporting. Se si usa una funzione lambda Visual Basic o un metodo anonimo C#, non fornire i parametri per il token e l'interfaccia **IProgress < t > ** .If you use a Visual Basic lambda function or a C# anonymous method, don't supply parameters for the token and IProgress<T> interface. Se usi una funzione lambda C#, fornisci un parametro per il token ma ignoralo.If you use a C# lambda function, supply a token parameter but ignore it. L'esempio precedente, che usava il < Metodo AsAsyncOperation TResult > , è simile al seguente quando si usa l'overload del metodo **AsyncInfo. Run < TResult > (Func < CancellationToken, Task < TResult > > **).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 si crea un metodo asincrono che supporta facoltativamente la creazione di report sull'annullamento o sullo stato di avanzamento, è consigliabile aggiungere overload che non dispongono di parametri per un token di annullamento o l'interfaccia **IProgress < t > ** .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.

Generazione di eccezioniThrowing exceptions

Puoi generare qualsiasi tipo di eccezione incluso in .NET per le app di Windows.You can throw any exception type that is included in the .NET for Windows apps. Non puoi dichiarare tipi di eccezione pubblici personalizzati in un componente Windows Runtime, ma puoi dichiarare e generare tipi non pubblici.You can't declare your own public exception types in a Windows Runtime component, but you can declare and throw non-public types.

Se il componente non gestisce l'eccezione, viene generata un'eccezione corrispondente nel codice che ha chiamato il componente.If your component doesn't handle the exception, a corresponding exception is raised in the code that called your component. La modalità di visualizzazione dell'eccezione da parte del chiamante dipende dalla modalità di supporto di Windows Runtime da parte del linguaggio chiamante.The way the exception appears to the caller depends on the way the calling language supports the Windows Runtime.

  • In JavaScript l'eccezione appare come un oggetto in cui il messaggio di eccezione è sostituito da un'analisi dello stack.In JavaScript, the exception appears as an object in which the exception message is replaced by a stack trace. Quando esegui il debug dell'app in Visual Studio, puoi vedere il testo del messaggio originale visualizzato nella finestra di dialogo di eccezione del debugger, identificato come "Informazioni 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". Non puoi accedere al testo del messaggio originale dal codice JavaScript.You can't access the original message text from JavaScript code.

    Suggerimento.Tip.Attualmente, la traccia stack contiene il tipo di eccezione gestita, ma non ti consigliamo di analizzare la traccia per identificare il tipo di eccezione. Currently, the stack trace contains the managed exception type, but we don't recommend parsing the trace to identify the exception type. Usa invece un valore HRESULT, come descritto più avanti in questa sezione.Instead, use an HRESULT value as described later in this section.

  • In C++ l'eccezione corrisponde a un'eccezione della piattaforma.In C++, the exception appears as a platform exception. Se è possibile eseguire il mapping della proprietà HResult dell'eccezione gestita al valore HRESULT di un'eccezione della piattaforma specifica, viene usata l'eccezione specifica. in caso contrario, viene generata un'eccezione Platform:: COMException .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. Il testo del messaggio dell'eccezione gestita non è disponibile nel codice C++.The message text of the managed exception is not available to C++ code. Se è stata generata un'eccezione della piattaforma specifica, viene visualizzato il testo del messaggio predefinito per tale tipo di eccezione. In caso contrario, non viene visualizzato alcun testo del messaggio.If a specific platform exception was thrown, the default message text for that exception type appears; otherwise, no message text appears. Vedi Eccezioni (C++/CX).See Exceptions (C++/CX).

  • In C# o in Visual Basic si tratta di una normale eccezione gestita.In C# or Visual Basic, the exception is a normal managed exception.

Quando generi un'eccezione dal componente, puoi semplificare la gestione dell'eccezione da parte di un chiamante JavaScript o C++ generando un tipo di eccezione non pubblico il cui valore della proprietà HResult sia specifico per il 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. HRESULT è disponibile per un chiamante JavaScript tramite la proprietà Number dell'oggetto Exception e per un chiamante C++ tramite la proprietà COMException:: HRESULT .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.

Nota

Usare un valore negativo per HRESULT.Use a negative value for your HRESULT. Un valore positivo viene interpretato come esito positivo e non viene generata alcuna eccezione nel chiamante JavaScript o C++.A positive value is interpreted as success, and no exception is thrown in the JavaScript or C++ caller.

Dichiarazione e generazione di eventiDeclaring and raising events

Quando dichiari un tipo per contenere i dati dell'evento, derivalo da Object anziché da EventArgs, perché EventArgs non è un tipo 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. Usare **EventHandler < TEventArgs > ** come tipo dell'evento e usare il tipo di argomento dell'evento come argomento di tipo generico.Use EventHandler<TEventArgs> as the type of the event, and use your event argument type as the generic type argument. Generare l'evento Analogamente a quanto avviene in un'applicazione .NET.Raise the event just as you would in a .NET application.

Quando il componente Windows Runtime viene usato da JavaScript o C++, l'evento segue lo schema di eventi di Windows Runtime previsto da questi linguaggi.When your Windows Runtime component is used from JavaScript or C++, the event follows the Windows Runtime event pattern that those languages expect. Quando si usa il componente da C# o Visual Basic, l'evento viene visualizzato come evento .NET normale.When you use the component from C# or Visual Basic, the event appears as an ordinary .NET event. Un esempio è disponibile nella procedura dettagliata per la creazione di un componente Windows Runtime C# o Visual Basic e la chiamata da JavaScript.An example is provided in Walkthrough of creating a C# or Visual Basic Windows Runtime component, and calling it from JavaScript.

Se implementi funzioni di accesso agli eventi personalizzate (dichiari un evento con la parola chiave Custom in Visual Basic), devi seguire lo schema di eventi di Windows Runtime nell'implementazione.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. Vedere eventi personalizzati e funzioni di accesso agli eventi nei componenti Windows Runtime.See Custom events and event accessors in Windows Runtime components. Si noti che quando si gestisce l'evento dal codice C# o Visual Basic, viene comunque visualizzato un evento .NET normale.Note that when you handle the event from C# or Visual Basic code, it still appears to be an ordinary .NET event.

Passaggi successiviNext steps

Dopo che hai creato un componente Windows Runtime, le funzionalità incapsulate possono risultare utili anche ad altri sviluppatori.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. Per creare il pacchetto di un componente per distribuirlo ad altri sviluppatori, puoi scegliere tra due possibilità.You have two options for packaging a component for distribution to other developers. Vedi Distribuzione di un componente Windows Runtime gestito.See Distributing a managed Windows Runtime component.

Per ulteriori informazioni sulle funzionalità del linguaggio Visual Basic e C# e sul supporto .NET per il Windows Runtime, vedere la pagina relativa ai riferimenti ai linguaggi Visual Basic e c#.For more information about Visual Basic and C# language features, and .NET support for the Windows Runtime, see Visual Basic and C# language reference.