Udržet vlákno uživatelského rozhraní responzivní

Uživatelé očekávají, že aplikace zůstane responzivní, i když provádí výpočty bez ohledu na typ počítače. To znamená různé věci pro různé aplikace – poskytuje realistickou fyziku, načítání dat z disku nebo webu, prezentaci složitých scén, navigaci mezi stránkami nebo zpracování dat. Bez ohledu na typ výpočtu chtějí uživatelé, aby vaše aplikace fungovala na jejich vstupu a eliminovala instance, ve kterých se zdá, že nereaguje.

Aplikace je řízená událostmi: váš kód funguje v reakci na událost a pak sedí nečinně až do další události. Kód platformy pro uživatelské rozhraní (rozložení, vstup, vyvolávání událostí) a kód aplikace pro uživatelské rozhraní se spouští ve stejném vlákně uživatelského rozhraní. Na daném vlákně se spustí jenom jedna instrukce, takže pokud zpracování události trvá příliš dlouho, architektura nemůže spustit rozložení ani vyvolat nové události. Rychlost odezvy aplikace souvisí s dostupností vlákna uživatelského rozhraní pro zpracování.

K provedení téměř všech změn prvků uživatelského rozhraní musíte použít vlákno uživatelského rozhraní. Uživatelské rozhraní nemůžete aktualizovat z vlákna na pozadí, ale můžete do něj publikovat zprávu pomocí DispatcherQueue.TryEnqueue , aby se tam spustil kód.

Important

V desktopových aplikacích WinUI 3 používejte DispatcherQueue místo UPW CoreDispatcher. Přistupujte k frontě dispečera přes vlastnost vašeho okna DispatcherQueue nebo DispatcherQueue.GetForCurrentThread().

Note

Samostatné vlákno vykreslení může použít změny uživatelského rozhraní, které nemají vliv na zpracování vstupu nebo základní rozložení. Mnoho animací a přechodů, které nemají vliv na rozložení, se například může spustit v tomto vlákně vykreslení.

Odložit vytvoření instance prvku

Mezi nejpomalejší fáze v aplikaci patří spuštění a přepínání zobrazení. Neproveďte více práce, než je nutné k vyvolání uživatelského rozhraní, které uživatel na začátku vidí. Například nevytvářit uživatelské rozhraní pro postupně zpřístupněný obsah nebo automaticky otevíraný obsah.

  • Použijte atribut x:Load k odloženému vytváření instancí prvků.
  • Programově vkládat prvky do stromu podle potřeby.

Použijte DispatcherQueue.TryEnqueue s nízkou prioritou, aby se práce zařadila do fronty a vlákno uživatelského rozhraní ji zpracovalo, když není vytížené.

Použití asynchronních rozhraní API

Pokud chcete, aby vaše aplikace reagovala, používejte asynchronní verze rozhraní API, když jsou k dispozici. Asynchronní API zajišťuje, že vaše aktivní vlákno provádění není nikdy zablokováno na delší dobu. Při volání rozhraní API z vlákna uživatelského rozhraní vždy použijte asynchronní verzi, pokud existuje.

Přesuňte zpracování na vlákna na pozadí

Napište obslužné rutiny událostí, které se mají rychle vrátit. Pokud je potřeba provést jiné než triviální množství práce, naplánujte ji na vlákně na pozadí a vraťte se.

Práci můžete naplánovat asynchronně pomocí operátoru await v jazyce C#. Nicméně await nezaručuje, že se práce spouští na vlákně na pozadí. Mnohá rozhraní API sady Windows App SDK za vás naplánují práci na vlákno na pozadí, ale pokud k volání kódu aplikace použijete pouze await, poběží tato metoda ve vlákně UI. Kód aplikace musíte explicitně spustit ve vlákně na pozadí. V jazyce C# toho dosáhnete předáním kódu do task.Run.

Mějte na paměti, že k prvkům uživatelského rozhraní můžete přistupovat pouze z vlákna uživatelského rozhraní. Vlákno uživatelského rozhraní použijte pro přístup k prvkům uživatelského rozhraní před spuštěním práce na pozadí nebo použijte DispatcherQueue.TryEnqueue vlákno na pozadí k publikování aktualizací uživatelského rozhraní zpět do vlákna uživatelského rozhraní.

public sealed partial class MainWindow : Window
{
    // Declared in MainWindow.xaml as x:Name="statusText".
    private TextBlock statusText;

    private async void NextMove_Click(object sender, RoutedEventArgs e)
    {
        // The await causes the handler to return immediately.
        await Task.Run(() => ComputeNextMove());

        // Now update the UI with the results.
        // This code runs on the UI thread after ComputeNextMove completes.
        statusText.Text = "Move computed.";
    }

    private void ComputeNextMove()
    {
        // Perform background work here.
        // Don't directly access UI elements from this method.
    }
}

V tomto příkladu se obslužná rutina NextMove_Click vrátí v bodě await, aby vlákno uživatelského rozhraní zůstalo responzivní. Po dokončení ComputeNextMove (která běží na vlákně na pozadí) pokračuje vykonávání v této obslužné rutině a zbývající kód aktualizuje uživatelské rozhraní podle výsledků.