A felhasználói felület szálának rugalmasan tartása

A felhasználók azt várják, hogy az alkalmazás a számítógép típusától függetlenül válaszkész marad, amíg számítást végez. Ez különböző dolgokat jelent a különböző alkalmazásokhoz – valósághű fizikát biztosít, adatokat tölt be a lemezről vagy a weből, összetett jeleneteket mutat be, navigál a lapok között, vagy adatokat dolgoz fel. A számítások típusától függetlenül a felhasználók azt szeretnék, hogy az alkalmazás a bemeneti adatok alapján működjön, és kiküszöbölje azokat a példányokat, ahol nem válaszolnak.

Az alkalmazás eseményvezérelt: a kód egy eseményre reagálva végzi a munkát, majd tétlenül ül a következő eseményig. A felhasználói felület platformkódja (elrendezés, bemenet, események emelése) és az alkalmazás felhasználói felületi kódja mind ugyanazon a felhasználói felületen fut. Egyszerre csak egy utasítás hajtja végre a szálat, így ha az alkalmazáskód túl sokáig tart egy esemény feldolgozásához, a keretrendszer nem tudja futtatni az elrendezést, és nem tud új eseményeket létrehozni. Az alkalmazás válaszképessége a felhasználói felület szálának a munka feldolgozásához való rendelkezésre állásához kapcsolódik.

A felhasználói felületi szál használatával szinte minden módosítást el kell végeznie a felhasználói felület elemein. A felhasználói felületet nem frissítheti háttérszálból, de a DispatcherQueue.TryEnqueue használatával közzétehet egy üzenetet, amely a kód ott való futtatását okozza.

Important

WinUI 3 asztali alkalmazásokban használja DispatcherQueue az UWP CoreDispatcherhelyett. Érje el a diszpécsersort az ablak DispatcherQueue tulajdonságán vagy a(z) DispatcherQueue.GetForCurrentThread() használatával.

Note

Egy különálló renderelési szál olyan felhasználói felületi módosításokat alkalmazhat, amelyek nem befolyásolják a bemenet kezelését vagy az alapszintű elrendezést. Ezen a renderelési szálon például számos olyan animáció és áttűnés futtatható, amelyek nem befolyásolják az elrendezést.

Az elem példányosításának késleltetése

Az alkalmazás leglassabb szakaszai közé tartozik az indítás és a nézetváltás. Ne végezze el a szükségesnél több munkát a felhasználó által kezdetben látott felhasználói felület létrehozásához. Például ne hozza létre a felhasználói felületet a fokozatosan közzétett tartalmakhoz vagy előugró tartalmakhoz.

  • Az elemek példányosításának késleltetéséhez használja a x:Load attribútumot.
  • Igény szerint programozott módon szúrjon be elemeket a fába.

Használja a(z) DispatcherQueue.TryEnqueue elemet alacsony prioritással a munka ütemezéséhez, hogy a felhasználói felület szála akkor dolgozza fel, amikor éppen nem foglalt.

Aszinkron API-k használata

Az alkalmazás válaszkészsége érdekében használja az API-k aszinkron verzióit, ha elérhetők. Az aszinkron API biztosítja, hogy az aktív végrehajtási szál ne blokkoljon jelentős ideig. Amikor meghív egy API-t a felhasználói felületi szálról, mindig használja az aszinkron verziót, ha létezik.

A munka háttérszálakra helyezése

Úgy írja meg az eseménykezelőket, hogy gyorsan visszatérjenek. Ha nem elhanyagolható mennyiségű munkát kell elvégezni, ütemezze azt háttérszálra, majd térjen vissza.

A C# operátorral aszinkron módon ütemezheti a await munkát. Azonban a await nem garantálja, hogy a munka háttérszálon fut. Számos Windows App SDK API háttérszálra ütemezi a munkát az Ön számára, de ha az alkalmazás kódját csak a(z) await használatával hívja meg, akkor az adott metódust az UI-szálon futtatja. Az alkalmazáskódot explicit módon kell futtatnia egy háttérszálon. A C#-ban ezt úgy hajthatja végre, hogy kódot ad át a Task.Runnak.

Ne feledje, hogy a felhasználói felület elemeihez csak a felhasználói felület száláról férhet hozzá. A felhasználói felület elemeinek eléréséhez a háttérmunka elindítása előtt használja a felhasználói felületi szálat, vagy a háttérszálon a DispatcherQueue.TryEnqueue használatával küldje vissza a felhasználói felület frissítéseit a felhasználói felületi szálra.

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.
    }
}

Ebben a példában a NextMove_Click kezelő a await pontnál tér vissza, hogy a felhasználói felület szála válaszképes maradjon. A végrehajtás újra elindul a kezelőben, miután ComputeNextMove (amely egy háttérszálon fut) befejeződik, és a fennmaradó kód frissíti a felhasználói felületet az eredményekkel.