Jaga agar utas UI tetap responsif

Pengguna mengharapkan aplikasi tetap responsif saat melakukan komputasi, terlepas dari jenis komputer. Ini berarti hal yang berbeda untuk aplikasi yang berbeda. Bagi sebagian orang, ini diterjemahkan untuk menyediakan fisika yang lebih realistis, memuat data dari disk atau web lebih cepat, dengan cepat menyajikan adegan kompleks dan menavigasi antar halaman, menemukan petunjuk arah dalam snap, atau memproses data dengan cepat. Terlepas dari jenis komputasi, pengguna ingin aplikasi mereka bertindak berdasarkan input mereka dan menghilangkan instans di mana aplikasi tersebut tampak tidak responsif saat "berpikir".

Aplikasi Anda digerakkan oleh peristiwa, yang berarti bahwa kode Anda melakukan pekerjaan sebagai respons terhadap peristiwa dan kemudian berada diam hingga yang berikutnya. Kode platform untuk UI (tata letak, input, peristiwa peningkatan, dll.) dan kode aplikasi Anda untuk UI semuanya dijalankan pada utas UI yang sama. Hanya satu instruksi yang dapat dijalankan pada utas tersebut pada satu waktu sehingga jika kode aplikasi Anda membutuhkan waktu terlalu lama untuk memproses peristiwa, kerangka kerja tidak dapat menjalankan tata letak atau menaikkan peristiwa baru yang mewakili interaksi pengguna. Responsivitas aplikasi Anda terkait dengan ketersediaan utas UI untuk memproses pekerjaan.

Anda perlu menggunakan utas UI untuk membuat hampir semua perubahan pada utas UI, termasuk membuat jenis UI dan mengakses anggota mereka. Anda tidak dapat memperbarui UI dari utas latar belakang tetapi Anda dapat memposting pesan ke UI tersebut dengan CoreDispatcher.RunAsync untuk menyebabkan kode dijalankan di sana.

Catatan Satu pengecualian adalah bahwa ada utas render terpisah yang dapat menerapkan perubahan UI yang tidak akan memengaruhi cara input ditangani atau tata letak dasar. Misalnya banyak animasi dan transisi yang tidak memengaruhi tata letak dapat berjalan pada utas render ini.

Penundaan instansiasi elemen

Beberapa tahap paling lambat dalam aplikasi dapat mencakup startup, dan beralih tampilan. Jangan melakukan lebih banyak pekerjaan daripada yang diperlukan untuk memunculkan UI yang dilihat pengguna pada awalnya. Misalnya, jangan membuat UI untuk UI yang diungkapkan secara progresif dan konten popup.

  • Gunakan atribut x:Load atau x:DeferLoadStrategy untuk menunda-instantiate elemen.
  • Sisipkan elemen secara terprogram ke pohon sesuai permintaan.

Antrean CoreDispatcher.RunIdleAsync berfungsi untuk utas UI untuk diproses saat tidak sibuk.

Menggunakan API asinkron

Untuk membantu menjaga aplikasi Anda tetap responsif, platform ini menyediakan versi asinkron dari banyak API-nya. API asinkron memastikan bahwa utas eksekusi aktif Anda tidak pernah memblokir untuk waktu yang signifikan. Saat Anda memanggil API dari utas UI, gunakan versi asinkron jika tersedia. Untuk informasi selengkapnya tentang pemrograman dengan pola asinkron , lihat Pemrograman asinkron atau Memanggil API asinkron di C# atau Visual Basic.

Pekerjaan offload ke utas latar belakang

Tulis penanganan aktivitas untuk kembali dengan cepat. Dalam kasus di mana jumlah pekerjaan yang tidak sepele perlu dilakukan, jadwalkan pada utas latar belakang dan kembali.

Anda dapat menjadwalkan pekerjaan secara asinkron dengan menggunakan operator tunggu di C#, operator Tunggu di Visual Basic, atau delegasi di C++. Tetapi ini tidak menjamin bahwa pekerjaan yang Anda jadwalkan akan berjalan pada utas latar belakang. Banyak API Platform Windows Universal (UWP) yang menjadwalkan pekerjaan di utas latar belakang untuk Anda, tetapi jika Anda memanggil kode aplikasi dengan hanya menunggu atau delegasi, Anda menjalankan delegasi atau metode tersebut di utas UI. Anda harus secara eksplisit mengatakan kapan Anda ingin menjalankan kode aplikasi di utas latar belakang. Di C# dan Visual Basic, Anda dapat menyelesaikan ini dengan meneruskan kode ke Task.Run.

Ingat bahwa elemen UI hanya dapat diakses dari utas UI. Gunakan utas UI untuk mengakses elemen UI sebelum meluncurkan pekerjaan latar belakang dan/atau menggunakan CoreDispatcher.RunAsync atau CoreDispatcher.RunIdleAsync pada utas latar belakang.

Contoh pekerjaan yang dapat dilakukan pada utas latar belakang adalah perhitungan AI komputer dalam permainan. Kode yang menghitung pemindahan komputer berikutnya dapat memakan banyak waktu untuk dijalankan.

public class AsyncExample
{
    private async void NextMove_Click(object sender, RoutedEventArgs e)
    {
        // The await causes the handler to return immediately.
        await System.Threading.Tasks.Task.Run(() => ComputeNextMove());
        // Now update the UI with the results.
        // ...
    }

    private async System.Threading.Tasks.Task ComputeNextMove()
    {
        // Perform background work here.
        // Don't directly access UI elements from this method.
    }
}
Public Class AsyncExample
    ' ...
    Private Async Sub NextMove_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Await Task.Run(Function() ComputeNextMove())
        ' update the UI with results
    End Sub

    Private Async Function ComputeNextMove() As Task
        ' ...
    End Function
    ' ...
End Class

Dalam contoh ini, NextMove_Click handler kembali pada menunggu untuk menjaga utas UI tetap responsif. Tetapi eksekusi mengambil di handler itu lagi setelah ComputeNextMove (yang dijalankan pada utas latar belakang) selesai. Kode yang tersisa dalam handler memperbarui UI dengan hasilnya.

Catatan Ada juga ThreadPool dan ThreadPoolTimer API untuk UWP, yang dapat digunakan untuk skenario serupa. Untuk informasi selengkapnya, lihat Pemrograman threading dan asinkron.