Creación de una aplicación universal de Windows de instancias múltiples
En este tema se describe cómo crear aplicaciones de la Plataforma Universal Windows (UWP) de instancias múltiples.
A partir de Windows 10, versión 1803 (10.0; compilación 17134), su app UWP puede optar por admitir instancias múltiples. Si se está ejecutando una instancia de una aplicación para UWP de varias instancias y llega una solicitud de activación posterior, la plataforma no activará la instancia existente. En su lugar, creará una instancia nueva, que se ejecutará en un proceso independiente.
Importante
La creación de instancias múltiples es compatible con aplicaciones JavaScript, pero la redirección de instancias múltiples no lo es. Dado que la redirección de instancias múltiples no es compatible con las aplicaciones JavaScript, la clase AppInstance no es útil para dichas aplicaciones.
Optar por el comportamiento de isntancia múltiple
Si está creando una nueva aplicación de instancia múltiple, puede instalar las Plantillas de proyecto de aplicación de instancia múltiple.VSIX, disponibles en Visual Studio Marketplace. Una vez instaladas las plantillas, estarán disponibles en el cuadro de diálogo Nuevo proyecto en Visual C# > Windows Universal (u Otros lenguajes > Visual C++ > Windows Universal).
Nota:
La plantilla Multi-Instance App Project ya no está disponible. La plantilla VSIX era cómoda, por lo que tendrá que modificar el proyecto existente en su lugar, como se describe a continuación. Asegúrese de añadir la constante DISABLE_XAML_GENERATED_MAIN a los símbolos de compilación del proyecto, ya que esto evita que la compilación genere un Main() por defecto. Esto permite el uso de una versión de Main() especialmente escrita para la aplicación.
Se instalan dos plantillas: Aplicación UWP de instancia múltiple, que proporciona la plantilla para crear una aplicación de instancia múltiple, y Aplicación UWP de redirección de instancia múltiple, que proporciona lógica adicional en la que puede basarse para lanzar una nueva instancia o activar selectivamente una instancia que ya se ha lanzado. Por ejemplo, puede que solo quiera una instancia a la vez editando el mismo documento, así que trae la instancia que tiene ese archivo abierto al primer plano en lugar de lanzar una nueva instancia.
Ambas plantillas SupportsMultipleInstances
se añaden al archivo package.appxmanifest
. Fíjese en el prefijo del espacio de nombres desktop4
y iot2
: solo los proyectos que tienen como objetivo el escritorio, o los proyectos del Internet de las Cosas (IoT), soportan las instancias múltiples.
<Package
...
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2"
IgnorableNamespaces="uap mp desktop4 iot2">
...
<Applications>
<Application Id="App"
...
desktop4:SupportsMultipleInstances="true"
iot2:SupportsMultipleInstances="true">
...
</Application>
</Applications>
...
</Package>
Redirección de activación de instancia múltiple
La compatibilidad de instancias múltiples para aplicaciones UWP va más allá de simplemente hacer posible el lanzamiento de múltiples instancias de la aplicación. Permite la personalización en casos en los que se desea seleccionar si se lanza una nueva instancia de la aplicación o si se activa una instancia que ya se está ejecutando. Por ejemplo, si la aplicación se inicia para editar un archivo que ya se está editando en otra instancia, es posible que desee redirigir la activación a esa instancia en lugar de abrir otra instancia que ya esté editando el archivo.
Para verlo en acción, vea este vídeo sobre Creación de aplicaciones UWP de instancia múltiple.
La plantilla Aplicación UWP de redirección de instancia múltiple añade SupportsMultipleInstances
al archivo package.appxmanifest como se muestra arriba, y también añade un Program.cs (o Program.cpp, si está usando la versión C++ de la plantilla) a su proyecto que contiene una función Main()
. La lógica para redirigir la activación va en la función Main
. La plantilla para Program.cs se muestra a continuación.
La propiedad AppInstance.RecommendedInstance representa la instancia preferida proporcionada por el shell para esta solicitud de activación, si existe (o null
si no existe). Si el shell proporciona una preferencia, puede redirigir la activación a esa instancia, o puede ignorarla si lo desea.
public static class Program
{
// This example code shows how you could implement the required Main method to
// support multi-instance redirection. The minimum requirement is to call
// Application.Start with a new App object. Beyond that, you may delete the
// rest of the example code and replace it with your custom code if you wish.
static void Main(string[] args)
{
// First, we'll get our activation event args, which are typically richer
// than the incoming command-line args. We can use these in our app-defined
// logic for generating the key for this instance.
IActivatedEventArgs activatedArgs = AppInstance.GetActivatedEventArgs();
// If the Windows shell indicates a recommended instance, then
// the app can choose to redirect this activation to that instance instead.
if (AppInstance.RecommendedInstance != null)
{
AppInstance.RecommendedInstance.RedirectActivationTo();
}
else
{
// Define a key for this instance, based on some app-specific logic.
// If the key is always unique, then the app will never redirect.
// If the key is always non-unique, then the app will always redirect
// to the first instance. In practice, the app should produce a key
// that is sometimes unique and sometimes not, depending on its own needs.
string key = Guid.NewGuid().ToString(); // always unique.
//string key = "Some-App-Defined-Key"; // never unique.
var instance = AppInstance.FindOrRegisterInstanceForKey(key);
if (instance.IsCurrentInstance)
{
// If we successfully registered this instance, we can now just
// go ahead and do normal XAML initialization.
global::Windows.UI.Xaml.Application.Start((p) => new App());
}
else
{
// Some other instance has registered for this key, so we'll
// redirect this activation to that instance instead.
instance.RedirectActivationTo();
}
}
}
}
Main()
es lo primero que se ejecuta. Se ejecuta antes de OnLaunched y OnActivated. Esto le permite determinar si activar esta, u otra instancia, antes de que se ejecute cualquier otro código de inicialización en su aplicación.
El código anterior determina si se activa una instancia existente o nueva de su aplicación. Se utiliza una clave para determinar si hay una instancia existente que desea activar. Por ejemplo, si su aplicación puede ser lanzada para Gestionar la activación de archivos, podría usar el nombre del archivo como clave. Entonces puede comprobar si una instancia de su aplicación ya está registrada con esa clave y activarla en lugar de abrir una nueva instancia. Esta es la idea tras del código: var instance = AppInstance.FindOrRegisterInstanceForKey(key);
Si se encuentra una instancia registrada con la clave, entonces esa instancia se activa. Si no se encuentra la clave, la instancia actual (la que se está ejecutando en ese momento Main
) crea su objeto de aplicación y comienza a ejecutarse.
Tareas en segundo plano y de instancia múltiple
- Las tareas en segundo plano fuera de proceso admiten el de instancia múltiple. Normalmente, cada nuevo desencadenador da lugar a una nueva instancia de la tarea en segundo plano (aunque técnicamente hablando pueden ejecutarse varias tareas en segundo plano en el mismo proceso de host). No obstante, se crea una instancia diferente de la tarea en segundo plano.
- Las tareas en segundo plano en proceso no admiten el de instancia múltiple.
- Las tareas de audio en segundo plano no admiten el de instancia múltiple.
- Cuando una aplicación registra una tarea en segundo plano, suele comprobar primero si la tarea ya está registrada y, a continuación, la elimina y la vuelve a registrar, o no hace nada para mantener el registro existente. Este sigue siendo el comportamiento típico de las aplicaciones de instancia múltiple. Sin embargo, una aplicación de instancia múltiple puede optar por registrar un nombre de tarea en segundo plano diferente para cada instancia. Esto resultará en múltiples registros para el mismo disparador, y múltiples instancias de tareas en segundo plano se activarán cuando se active el disparador.
- Los servicios de aplicaciones lanzan una instancia separada de la tarea en segundo plano del servicio de aplicación para cada conexión. Esto no cambia en el caso de las aplicaciones de instancia múltiple, es decir, cada instancia de una aplicación de instancia múltiple obtendrá su propia instancia de la tarea en segundo plano del servicio de aplicaciones.
Consideraciones adicionales
- Las aplicaciones UWP destinadas a proyectos de escritorio e Internet de las Cosas (IoT) admiten la de instancia múltiple.
- Para evitar condiciones de carrera y problemas de contención, las aplicaciones de instancia múltiple deben tomar medidas para particionar/sincronizar el acceso a la configuración, el almacenamiento local de la aplicación y cualquier otro recurso (como archivos de usuario, un almacén de datos, etc.) que pueda compartirse entre varias instancias. Los mecanismos de sincronización estándar como mutexes, semáforos, eventos, etc., están disponibles.
- Si la aplicación tiene
SupportsMultipleInstances
en su archivo Package.appxmanifest, entonces sus extensiones no necesitan declararSupportsMultipleInstances
. - Si añade
SupportsMultipleInstances
a cualquier otra extensión, aparte de tareas en segundo plano o servicios de aplicación y la aplicación que aloja la extensión no declara tambiénSupportsMultipleInstances
en su fichero Package.appxmanifest, entonces se genera un error de esquema. - Las aplicaciones pueden utilizar la declaración ResourceGroup en su manifiesto para agrupar varias tareas en segundo plano en el mismo host. Esto entra en conflicto con las instancias múltiples donde cada activación va a un host separado. Por lo tanto, una aplicación no puede declarar
SupportsMultipleInstances
yResourceGroup
en su manifiesto.
Ejemplo
Consulte Ejemplo de de instancia múltiple para ver un ejemplo de redirección de activación de instancia múltiple.
Consulte también
AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToGestionar activación de la aplicación