Udostępnij przez


Tworzenie aplikacji uniwersalnej na Windows z wieloma wystąpieniami

Ten temat opisuje, jak tworzyć aplikacje platformy Uniwersalnej Windows (UWP) umożliwiające wiele instancji.

Od systemu Windows 10, wersja 1803 (10.0; Kompilacja 17134) wzwyż, aplikacja platformy UWP może zdecydować się na obsługę wielu wystąpień. Jeśli jest uruchomione wystąpienie wieloinstancyjnej aplikacji UWP, a pojawi się kolejne żądanie aktywacji, platforma nie aktywuje istniejącego wystąpienia. Zamiast tego utworzy nowe wystąpienie uruchomione w osobnym procesie.

Włączanie obsługi wielu instancji

Jeśli tworzysz nową wieloinstancyjną aplikację, możesz zainstalować szablony projektów aplikacji wieloinstancyjnych .VSIX, dostępne na Marketplace Visual Studio . Po zainstalowaniu szablonów będą one dostępne w oknie dialogowym Nowy projekt w obszarze Uniwersalny system Windows Visual C# > (lub Inne języki > Visual C++ > Universal).

Uwaga / Notatka

Szablon projektu aplikacji z wieloma wystąpieniami nie jest już dostępny. Szablon VSIX był ułatwieniem, dlatego musisz zmodyfikować istniejący projekt, jak opisano poniżej. Pamiętaj, aby dodać stałą DISABLE_XAML_GENERATED_MAIN do symboli kompilacji projektu, ponieważ uniemożliwia to wygenerowanie przez kompilację domyślnego main(). Umożliwia to użycie specjalnie napisanej, dedykowanej dla aplikacji wersji Main().

Instalowane są dwa szablony: aplikacji platformy UWP z wieloma wystąpieniami, która udostępnia szablon do tworzenia aplikacji z wieloma wystąpieniami, oraz aplikacji platformy UWP z przekierowaniem z wieloma wystąpieniami, która zapewnia dodatkową logikę, którą można rozbudować w celu uruchomienia nowego wystąpienia lub selektywnego aktywowania wystąpienia, które zostało już uruchomione. Na przykład, być może chcesz mieć tylko jedno wystąpienie edytujące ten sam dokument jednocześnie, dlatego przenosisz na pierwszy plan wystąpienie, które ma otwarty ten plik, zamiast uruchamiania nowego wystąpienia.

Oba szablony dodają SupportsMultipleInstances do pliku package.appxmanifest. Zwróć uwagę na prefiks desktop4 przestrzeni nazw: tylko projekty przeznaczone dla pulpitu obsługują wielokrotne instancjonowanie.

Uwaga / Notatka

Jeśli aplikacja jest przeznaczona dla systemu Windows 10 w wersji 2004 (kompilacja 19041) lub nowszej, możesz użyć nowszego uap10:SupportsMultipleInstances atrybutu zamiast desktop4:SupportsMultipleInstances. uap10 Przestrzeń nazw jest preferowanym podejściem dla nowszych aplikacji.

<Package
  ...
  xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
  IgnorableNamespaces="uap mp desktop4">
  ...
  <Applications>
    <Application Id="App"
      ...
      desktop4:SupportsMultipleInstances="true">
      ...
    </Application>
  </Applications>
   ...
</Package>

Przekierowywanie aktywacji z wieloma instancjami

Obsługa wielu instancji dla aplikacji UWP wykracza poza samo umożliwienie uruchamiania wielu wystąpień aplikacji. Umożliwia to dostosowanie w przypadkach, w których chcesz wybrać, czy nowe wystąpienie aplikacji jest uruchomione, czy wystąpienie, które jest już uruchomione, jest aktywowane. Jeśli na przykład aplikacja zostanie uruchomiona w celu edycji pliku, który jest już edytowany w innym wystąpieniu, możesz przekierować aktywację do tego wystąpienia zamiast otwierać inne wystąpienie, które już edytuje plik.

Aby zobaczyć to w akcji, obejrzyj ten film na temat tworzenia aplikacji UWP z wieloma wystąpieniami.

Szablon aplikacji przekierowania wielu wystąpień platformy UWP dodaje element do pliku package.appxmanifest zgodnie z powyższym przykładem, a także dodaje plik Program.cs (lub Program.cpp, jeśli używasz wersji języka C++ szablonu) do projektu, który zawiera funkcję . Logika przekierowywania aktywacji znajduje się w funkcji Main. Poniżej przedstawiono szablon Program.cs .

Właściwość AppInstance.RecommendedInstance reprezentuje obsługiwane przez powłokę wystąpienie preferowane dla tego żądania aktywacji, jeśli istnieje (lub null jeśli nie istnieje). Jeśli powłoka zapewnia preferencję, możesz przekierować aktywację do tego wystąpienia lub zignorować je, jeśli wybierzesz.

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() jest pierwszą rzeczą, która działa. Jest uruchamiany przed OnLaunched i OnActivated. Dzięki temu można określić, czy aktywować tę instancję, czy inną, zanim jakikolwiek inny kod inicjalizacji w aplikacji zostanie uruchomiony.

Powyższy kod określa, czy jest aktywowane istniejące, czy nowe wystąpienie aplikacji. Klucz służy do określania, czy istnieje istniejące wystąpienie, które chcesz aktywować. Jeśli na przykład można uruchomić aplikację w celu Obsługa aktywacji plików, możesz użyć nazwy pliku jako klucza. Następnie możesz sprawdzić, czy wystąpienie aplikacji jest już zarejestrowane przy użyciu tego klucza, i aktywować je zamiast otwierać nowe wystąpienie. Jest to pomysł związany z kodem: var instance = AppInstance.FindOrRegisterInstanceForKey(key);

Jeśli wystąpienie zarejestrowane przy użyciu klucza zostanie znalezione, to wystąpienie zostanie aktywowane. Jeśli klucz nie zostanie znaleziony, bieżące wystąpienie (wystąpienie, które jest obecnie uruchomione Main), tworzy swój obiekt aplikacji i zaczyna działać.

Zadania w tle i wiele instancji

  • Zadania w tle poza procesem obsługują wieloinstancjonowanie. Zazwyczaj każdy nowy wyzwalacz powoduje utworzenie nowego wystąpienia zadania w tle (chociaż technicznie rzecz biorąc, wiele zadań w tle może być uruchamianych w tym samym procesie hosta). Niemniej, tworzone jest nowe wystąpienie zadania w tle.
  • Zadania w tle in-proc nie obsługują wieloinstancyjności.
  • Zadania audio w tle nie obsługują wielokrotnych wystąpień.
  • Gdy aplikacja rejestruje zadanie w tle, zwykle najpierw sprawdza, czy zadanie jest już zarejestrowane, a następnie usuwa je i ponownie rejestruje lub nie wykonuje żadnych czynności w celu zachowania istniejącej rejestracji. Jest to nadal typowe zachowanie w przypadku aplikacji z wieloma wystąpieniami. Jednak aplikacja wieloinstancyjna może zdecydować się na zarejestrowanie innej nazwy zadania w tle dla każdego z wystąpień. Spowoduje to wiele rejestracji dla tego samego wyzwalacza, a po wyzwoleniu wyzwalacza zostanie aktywowanych wiele wystąpień zadań w tle.
  • Usługa App-Service uruchamia oddzielne wystąpienie zadania w tle dla każdego połączenia. Pozostaje to niezmienione w przypadku aplikacji z wieloma instancjami, to znaczy każda z nich otrzyma swoje własne zadanie w tle usługi aplikacji.

Uwagi dodatkowe

  • Multi-instancing jest obsługiwany przez aplikacje platformy UWP przeznaczone dla projektów komputerów stacjonarnych.
  • Aby uniknąć problemów z wyścigiem i konfliktów, aplikacje z wieloma instancjami muszą podjąć działania w celu partycjonowania/synchronizowania dostępu do ustawień, lokalnej pamięci aplikacji oraz innych zasobów (na przykład plików użytkownika, magazynu danych itp.), które mogą być współdzielone między wieloma instancjami. Dostępne są standardowe mechanizmy synchronizacji, takie jak muteksy, semafory, zdarzenia itd.
  • Jeśli aplikacja ma SupportsMultipleInstances w swoim pliku Package.appxmanifest, rozszerzenia nie muszą deklarować SupportsMultipleInstances.
  • Jeśli dodasz SupportsMultipleInstances do innego rozszerzenia oprócz zadań w tle lub usług app-services, a aplikacja, która hostuje rozszerzenie, nie deklaruje SupportsMultipleInstances również w pliku Package.appxmanifest, zostanie wygenerowany błąd schematu.
  • Aplikacje mogą używać deklaracji ResourceGroup w manifeście, aby zgrupować wiele zadań w tle na tym samym hoście. Powoduje to konflikt z wieloma instancjami, gdzie każda aktywacja trafia do oddzielnego hosta. W związku z tym aplikacja nie może zadeklarować zarówno SupportsMultipleInstances jak i ResourceGroup w manifeście.

Przykład

Zobacz przykład z wieloma wystąpieniami, aby zapoznać się z przekierowaniem aktywacji dla wielu wystąpień.

Zobacz także

AppInstance.FindOrRegisterInstanceForKeyAppInstance.GetActivatedEventArgsAppInstance.RedirectActivationToObsługa aktywacji aplikacji