Menunda penangguhan aplikasi dengan eksekusi yang diperpanjang

Artikel ini menunjukkan cara menggunakan eksekusi yang diperluas untuk menunda saat aplikasi ditangguhkan sehingga dapat berjalan saat diminimalkan atau di bawah layar kunci.

Saat pengguna meminimalkan atau beralih menjauh dari aplikasi, pengguna akan dimasukkan ke dalam status ditangguhkan. Memorinya dipertahankan, tetapi kodenya tidak berjalan. Ini berlaku di semua Edisi OS dengan antarmuka pengguna visual. Untuk detail selengkapnya tentang kapan aplikasi Anda ditangguhkan, lihat Siklus Hidup Aplikasi.

Ada kasus di mana aplikasi mungkin perlu terus berjalan, daripada ditangguhkan, ketika pengguna menavigasi jauh dari aplikasi, atau saat diminimalkan. Misalnya, aplikasi penghitungan langkah perlu terus berjalan dan melacak langkah-langkah bahkan ketika pengguna menavigasi jauh untuk menggunakan aplikasi lain.

Jika aplikasi perlu terus berjalan, OS dapat membuatnya tetap berjalan, atau dapat meminta untuk terus berjalan. Misalnya, saat memutar audio di latar belakang, OS dapat membuat aplikasi tetap berjalan lebih lama jika Anda mengikuti langkah-langkah ini untuk Pemutaran Media Latar Belakang. Jika tidak, Anda harus meminta lebih banyak waktu secara manual. Jumlah waktu yang mungkin Anda dapatkan untuk melakukan eksekusi latar belakang mungkin beberapa menit tetapi Anda harus siap untuk menangani sesi yang dicabut kapan saja. Batasan waktu siklus hidup aplikasi ini dinonaktifkan saat aplikasi berjalan di bawah debugger. Untuk alasan ini, penting untuk menguji Extended Execution dan alat lain untuk menunda penangguhan aplikasi saat tidak berjalan di bawah debugger atau dengan menggunakan Peristiwa Siklus Hidup yang tersedia di Visual Studio.

Buat ExtendedExecutionSession untuk meminta lebih banyak waktu untuk menyelesaikan operasi di latar belakang. Jenis ExtendedExecutionSession yang Anda buat ditentukan oleh ExtendedExecutionReason yang Anda berikan saat membuatnya. Ada tiga nilai enum ExtendedExecutionReason : Unspecified, LocationTracking dan SavingData. Hanya satu ExtendedExecutionSession yang dapat diminta kapan saja; mencoba membuat sesi lain saat permintaan sesi yang disetujui saat ini aktif akan menyebabkan pengecualian 0x8007139F dilemparkan dari konstruktor ExtendedExecutionSession yang menyatakan bahwa grup atau sumber daya tidak dalam status yang benar untuk melakukan operasi yang diminta. Jangan gunakan ExtendedExecutionForegroundSession dan ExtendedExecutionForegroundReason; mereka memerlukan kemampuan terbatas dan tidak tersedia untuk digunakan dalam aplikasi Store.

Jalankan saat diminimalkan

Ada dua kasus di mana eksekusi yang diperpanjang dapat digunakan:

  • Kapan saja selama eksekusi latar depan reguler, saat aplikasi dalam keadaan berjalan.
  • Setelah aplikasi menerima peristiwa penangguhan (OS akan memindahkan aplikasi ke status ditangguhkan) dalam penanganan aktivitas yang ditangguhkan aplikasi.

Kode untuk kedua kasus ini sama, tetapi aplikasi berperilaku sedikit berbeda di masing-masing kasus. Dalam kasus pertama, aplikasi tetap dalam status berjalan, bahkan jika peristiwa yang biasanya akan memicu penangguhan terjadi (misalnya, pengguna menavigasi jauh dari aplikasi). Aplikasi tidak akan pernah menerima peristiwa penangguhan saat ekstensi eksekusi berlaku. Ketika ekstensi dibuang, aplikasi menjadi memenuhi syarat untuk penangguhan lagi.

Dalam kasus kedua, jika aplikasi beralih ke status ditangguhkan, aplikasi akan tetap dalam status menangguhkan untuk periode perpanjangan. Setelah ekstensi kedaluwarsa, aplikasi memasuki status ditangguhkan tanpa pemberitahuan lebih lanjut.

Gunakan ExtendedExecutionReason.Unspecified saat Anda membuat ExtendedExecutionSession untuk meminta waktu tambahan sebelum aplikasi Anda berpindah ke latar belakang untuk skenario seperti pemrosesan media, kompilasi proyek, atau menjaga koneksi jaringan tetap hidup. Pada perangkat desktop yang berjalan Windows 10 untuk edisi desktop (Home, Pro, Enterprise, dan Education), ini adalah pendekatan untuk digunakan jika aplikasi perlu menghindari ditangguhkan saat diminimalkan.

Minta ekstensi saat memulai operasi jangka panjang untuk menunda transisi Status penangguhan yang jika tidak terjadi saat aplikasi berpindah ke latar belakang. Pada perangkat desktop, sesi eksekusi yang diperluas yang dibuat dengan ExtendedExecutionReason.Unspecified memiliki batas waktu sadar baterai. Jika perangkat terhubung ke daya dinding, tidak ada batasan untuk panjang periode waktu eksekusi yang diperpanjang. Jika perangkat menggunakan daya baterai, periode waktu eksekusi yang diperpanjang dapat berjalan hingga sepuluh menit di latar belakang.

Pengguna tablet atau laptop bisa mendapatkan perilaku jangka panjang yang sama--dengan mengorbankan masa pakai baterai--ketika opsi Izinkan aplikasi menjalankan tugas latar belakang dipilih dalam Penggunaan baterai oleh pengaturan aplikasi . (Untuk menemukan opsi ini di laptop, buka Pengaturan>Sistem>Baterai>Penggunaan baterai menurut Aplikasi (tautan di bawah persentase sisa daya baterai) > pilih aplikasi >matikan Dikelola Oleh Windows> pilih Izinkan aplikasi untuk menjalankan tugas latar belakang.

Pada semua edisi OS, sesi eksekusi yang diperluas ini berhenti saat perangkat memasuki Connected Standby. Pada perangkat seluler yang menjalankan Windows 10 Mobile, sesi eksekusi yang diperluas ini akan berjalan selama layar menyala. Saat layar dimatikan, perangkat segera mencoba memasuki mode Connected-Standby berdaya rendah. Pada perangkat desktop, sesi akan terus berjalan jika layar kunci muncul. Perangkat tidak memasukkan Siaga Tersambung untuk jangka waktu tertentu setelah layar dimatikan. Pada Xbox OS Edition, perangkat memasukkan Connect Standby setelah satu jam kecuali pengguna mengubah default.

Melacak lokasi pengguna

Tentukan ExtendedExecutionReason.LocationTracking saat Anda membuat ExtendedExecutionSession jika aplikasi Anda perlu mencatat lokasi secara teratur dari GeoLocator. Aplikasi untuk pelacakan dan navigasi kebugaran yang perlu memantau lokasi pengguna secara teratur dan harus menggunakan alasan ini.

Sesi eksekusi yang diperluas pelacakan lokasi dapat berjalan selama diperlukan, termasuk saat layar dikunci pada perangkat seluler. Namun, hanya boleh ada satu sesi seperti itu yang berjalan per perangkat. Sesi eksekusi yang diperluas pelacakan lokasi hanya dapat diminta di latar depan, dan aplikasi harus dalam status Berjalan . Ini memastikan bahwa pengguna menyadari bahwa aplikasi telah memulai sesi pelacakan lokasi yang diperluas. Masih dimungkinkan untuk menggunakan GeoLocator saat aplikasi berada di latar belakang dengan menggunakan tugas latar belakang, atau layanan aplikasi, tanpa meminta pelacakan lokasi sesi eksekusi yang diperluas.

Simpan Data Penting Secara Lokal

Tentukan ExtendedExecutionReason.SavingData saat Anda membuat ExtendedExecutionSession untuk menyimpan data pengguna jika tidak menyimpan data sebelum aplikasi dihentikan akan mengakibatkan kehilangan data dan pengalaman pengguna yang negatif.

Jangan gunakan sesi semacam ini untuk memperpanjang masa pakai aplikasi untuk mengunggah atau mengunduh data. Jika Anda perlu mengunggah data, minta transfer latar belakang atau daftarkan MaintenanceTrigger untuk menangani transfer saat daya AC tersedia. Sesi eksekusi extendedExecutionReason.SavingData dapat diminta baik saat aplikasi berada di latar depan dan dalam status Berjalan , atau di latar belakang dan dalam status Menangguhkan .

Status Penangguhan adalah kesempatan terakhir selama siklus hidup aplikasi yang dapat dilakukan aplikasi sebelum aplikasi dihentikan. ExtendedExecutionReason.SavingData adalah satu-satunya jenis ExtendedExecutionSession yang dapat diminta dalam status Menangguhkan . Meminta extendedExecutionReason.SavingData memperpanjang sesi eksekusi saat aplikasi berada dalam status Menangguhkan menciptakan masalah potensial yang harus Anda ketahui. Jika sesi eksekusi yang diperpanjang diminta saat dalam status Penangguhan , dan pengguna meminta aplikasi diluncurkan lagi, mungkin perlu waktu lama untuk diluncurkan. Ini karena periode waktu sesi eksekusi yang diperpanjang harus selesai sebelum instans lama aplikasi dapat ditutup dan instans baru aplikasi dapat diluncurkan. Waktu performa peluncuran dikorbankan untuk menjamin bahwa status pengguna tidak hilang.

Permintaan, pembuangan, dan pencabutan

Ada tiga interaksi mendasar dengan sesi eksekusi yang diperpanjang: permintaan, pembuangan, dan pencabutan. Membuat permintaan dimodelkan dalam cuplikan kode berikut.

Minta

var newSession = new ExtendedExecutionSession();
newSession.Reason = ExtendedExecutionReason.Unspecified;
newSession.Revoked += SessionRevoked;
ExtendedExecutionResult result = await newSession.RequestExtensionAsync();

switch (result)
{
    case ExtendedExecutionResult.Allowed:
        DoLongRunningWork();
        break;

    default:
    case ExtendedExecutionResult.Denied:
        DoShortRunningWork();
        break;
}

Lihat sampel kode

Memanggil RequestExtensionAsync memeriksa dengan sistem operasi untuk melihat apakah pengguna telah menyetujui aktivitas latar belakang untuk aplikasi dan apakah sistem memiliki sumber daya yang tersedia untuk mengaktifkan eksekusi latar belakang. Hanya satu sesi yang akan disetujui untuk aplikasi kapan saja, menyebabkan panggilan tambahan ke RequestExtensionAsync mengakibatkan sesi ditolak.

Anda dapat memeriksa BackgroundExecutionManager sebelumnya untuk menentukan BackgroundAccessStatus, yang merupakan pengaturan pengguna yang menunjukkan apakah aplikasi Anda dapat berjalan di latar belakang atau tidak. Untuk mempelajari selengkapnya tentang pengaturan pengguna ini, lihat Aktivitas Latar Belakang dan Kesadaran Energi.

ExtendedExecutionReason menunjukkan operasi yang dilakukan aplikasi Anda di latar belakang. String Deskripsi adalah string yang dapat dibaca manusia yang menjelaskan mengapa aplikasi Anda perlu melakukan operasi. String ini tidak disajikan kepada pengguna, tetapi mungkin tersedia dalam rilis Windows di masa mendatang. Penanganan aktivitas yang dicabut diperlukan sehingga sesi eksekusi yang diperpanjang dapat berhenti dengan baik jika pengguna, atau sistem, memutuskan bahwa aplikasi tidak dapat lagi berjalan di latar belakang.

Dicabut

Jika aplikasi memiliki sesi eksekusi yang diperluas aktif dan sistem memerlukan aktivitas latar belakang untuk berhenti karena aplikasi latar depan memerlukan sumber daya, maka sesi dicabut. Periode waktu sesi eksekusi yang diperpanjang tidak pernah dihentikan tanpa terlebih dahulu memecat penanganan aktivitas yang dicabut .

Ketika peristiwa Dicabut diaktifkan untuk sesi eksekusi extendedExecutionReason.SavingData yang diperpanjang, aplikasi memiliki satu detik untuk menyelesaikan operasi yang dilakukannya dan menyelesaikan Penangguhan.

Pencabutan dapat terjadi karena berbagai alasan: batas waktu eksekusi tercapai, kuota energi latar belakang tercapai, atau memori perlu diklaim kembali agar pengguna membuka aplikasi baru di latar depan.

Berikut adalah contoh penanganan aktivitas yang Dicabut:

private async void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        switch (args.Reason)
        {
            case ExtendedExecutionRevokedReason.Resumed:
                rootPage.NotifyUser("Extended execution revoked due to returning to foreground.", NotifyType.StatusMessage);
                break;

            case ExtendedExecutionRevokedReason.SystemPolicy:
                rootPage.NotifyUser("Extended execution revoked due to system policy.", NotifyType.StatusMessage);
                break;
        }

        EndExtendedExecution();
    });
}

Lihat sampel kode

Dispose

Langkah terakhir adalah membuang sesi eksekusi yang diperpanjang. Anda ingin membuang sesi, dan aset intensif memori lainnya, karena jika tidak, energi yang digunakan oleh aplikasi saat menunggu sesi ditutup akan dihitung terhadap kuota energi aplikasi. Untuk mempertahankan kuota energi sebanyak mungkin untuk aplikasi, penting untuk membuang sesi ketika Anda selesai dengan pekerjaan Anda untuk sesi sehingga aplikasi dapat pindah ke status Ditangguhkan dengan lebih cepat.

Membuang sesi sendiri, daripada menunggu peristiwa pencabutan, mengurangi penggunaan kuota energi aplikasi Anda. Ini berarti bahwa aplikasi Anda akan diizinkan untuk berjalan di latar belakang lebih lama di sesi mendatang karena Anda akan memiliki lebih banyak kuota energi yang tersedia untuk melakukannya. Anda harus mempertahankan referensi ke objek ExtendedExecutionSession hingga akhir operasi sehingga Anda dapat memanggil metode Buangnya .

Cuplikan yang membuang sesi eksekusi yang diperluas mengikuti:

void ClearExtendedExecution(ExtendedExecutionSession session)
{
    if (session != null)
    {
        session.Revoked -= SessionRevoked;
        session.Dispose();
        session = null;
    }
}

Lihat sampel kode

Aplikasi hanya dapat memiliki satu ExtendedExecutionSession yang aktif pada satu waktu. Banyak aplikasi menggunakan tugas asinkron untuk menyelesaikan operasi kompleks yang memerlukan akses ke sumber daya seperti penyimpanan, jaringan, atau layanan berbasis jaringan. Jika operasi memerlukan beberapa tugas asinkron untuk diselesaikan, maka status masing-masing tugas ini harus dipertanggungjawabkan sebelum membuang ExtendedExecutionSession dan memungkinkan aplikasi ditangguhkan. Ini memerlukan referensi yang menghitung jumlah tugas yang masih berjalan, dan tidak membuang sesi hingga nilai tersebut mencapai nol.

Berikut adalah beberapa contoh kode untuk mengelola beberapa tugas selama periode sesi eksekusi yang diperpanjang. Untuk informasi selengkapnya tentang cara menggunakan ini di aplikasi Anda, silakan lihat sampel kode yang ditautkan di bawah ini:

static class ExtendedExecutionHelper
{
    private static ExtendedExecutionSession session = null;
    private static int taskCount = 0;

    public static bool IsRunning
    {
        get
        {
            if (session != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    public static async Task<ExtendedExecutionResult> RequestSessionAsync(ExtendedExecutionReason reason, TypedEventHandler<object, ExtendedExecutionRevokedEventArgs> revoked, String description)
    {
        // The previous Extended Execution must be closed before a new one can be requested.       
        ClearSession();

        var newSession = new ExtendedExecutionSession();
        newSession.Reason = reason;
        newSession.Description = description;
        newSession.Revoked += SessionRevoked;

        // Add a revoked handler provided by the app in order to clean up an operation that had to be halted prematurely
        if(revoked != null)
        {
            newSession.Revoked += revoked;
        }

        ExtendedExecutionResult result = await newSession.RequestExtensionAsync();

        switch (result)
        {
            case ExtendedExecutionResult.Allowed:
                session = newSession;
                break;
            default:
            case ExtendedExecutionResult.Denied:
                newSession.Dispose();
                break;
        }
        return result;
    }

    public static void ClearSession()
    {
        if (session != null)
        {
            session.Dispose();
            session = null;
        }

        taskCount = 0;
    }

    public static Deferral GetExecutionDeferral()
    {
        if (session == null)
        {
            throw new InvalidOperationException("No extended execution session is active");
        }

        taskCount++;
        return new Deferral(OnTaskCompleted);
    }

    private static void OnTaskCompleted()
    {
        if (taskCount > 0)
        {
            taskCount--;
        }
        
        //If there are no more running tasks than end the extended lifetime by clearing the session
        if (taskCount == 0 && session != null)
        {
            ClearSession();
        }
    }

    private static void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
    {
        //The session has been prematurely revoked due to system constraints, ensure the session is disposed
        if (session != null)
        {
            session.Dispose();
            session = null;
        }
        
        taskCount = 0;
    }
}

Lihat sampel kode

Pastikan aplikasi Anda menggunakan sumber daya dengan baik

Menyetel memori dan penggunaan energi aplikasi Anda adalah kunci untuk memastikan bahwa sistem operasi akan memungkinkan aplikasi Anda untuk terus berjalan saat bukan lagi aplikasi latar depan. Gunakan API Manajemen Memori untuk melihat berapa banyak memori yang digunakan aplikasi Anda. Semakin banyak memori yang digunakan aplikasi Anda, semakin sulit bagi OS untuk menjaga aplikasi Anda tetap berjalan saat aplikasi lain berada di latar depan. Pengguna pada akhirnya memegang kendali atas semua aktivitas latar belakang yang dapat dilakukan aplikasi Anda dan memiliki visibilitas pada dampak yang dimiliki aplikasi Anda terhadap penggunaan baterai.

Gunakan BackgroundExecutionManager.RequestAccessAsync untuk menentukan apakah pengguna telah memutuskan bahwa aktivitas latar belakang aplikasi Anda harus dibatasi. Waspadai penggunaan baterai Anda dan hanya berjalan di latar belakang ketika perlu untuk menyelesaikan tindakan yang diinginkan pengguna.

Lihat juga

Sampel Eksekusi yang Diperluas
Siklus Hidup Aplikasi
Siklus Hidup Aplikasi - Menjaga Aplikasi Tetap Hidup dengan Tugas Latar Belakang danManajemen Memori Latar Belakang Eksekusi yang Diperluas
Transfer Latar Belakang
Kesadaran Baterai dan Aktivitas Latar Belakang
Kelas MemoryManager
Putar Media di Latar Belakang