Bagikan melalui


Ringkasan Bab 20. Asinkron dan I/O file

Catatan

Buku ini diterbitkan pada musim semi 2016, dan belum diperbarui sejak saat itu. Ada banyak dalam buku yang tetap berharga, tetapi beberapa materi sudah kedaluarsa, dan beberapa topik tidak lagi sepenuhnya benar atau lengkap.

Antarmuka pengguna grafis harus merespons peristiwa input pengguna secara berurutan. Ini menyiratkan bahwa semua pemrosesan peristiwa input pengguna harus terjadi dalam satu utas, sering disebut utas utama atau utas UI.

Pengguna mengharapkan antarmuka pengguna grafis responsif. Ini berarti bahwa program harus memproses peristiwa input pengguna dengan cepat. Jika itu tidak memungkinkan, maka pemrosesan harus direlegasikan ke utas eksekusi sekunder.

Beberapa contoh program dalam buku ini telah menggunakan WebRequest kelas . Di kelas BeginGetResponse ini, metode memulai utas pekerja, yang memanggil fungsi panggilan balik ketika selesai. Namun, fungsi panggilan balik tersebut berjalan di utas pekerja, sehingga program harus memanggil Device.BeginInvokeOnMainThread metode untuk mengakses antarmuka pengguna.

Catatan

Xamarin.Forms program harus menggunakan HttpClient daripada WebRequest mengakses file melalui internet. HttpClient mendukung operasi asinkron.

Pendekatan yang lebih modern untuk pemrosesan asinkron tersedia di .NET dan C#. Ini melibatkan Task kelas dan Task<TResult> , dan jenis lain di System.Threading namespace layanan dan System.Threading.Tasks , serta C# 5.0 async dan await kata kunci. Itulah yang difokuskan bab ini.

Dari panggilan balik hingga menunggu

Kelas itu Page sendiri berisi tiga metode asinkron untuk menampilkan kotak pemberitahuan:

Objek Task menunjukkan bahwa metode ini mengimplementasikan Pola Asinkron berbasis Tugas, yang dikenal sebagai TAP. Objek-objek ini Task dikembalikan dengan cepat dari metode . Nilai Task<T> pengembalian merupakan "janji" bahwa nilai jenis TResult akan tersedia saat tugas selesai. Nilai Task pengembalian menunjukkan tindakan asinkron yang akan selesai tetapi tanpa nilai yang dikembalikan.

Dalam semua kasus ini, Task selesai ketika pengguna menutup kotak pemberitahuan.

Pemberitahuan dengan panggilan balik

Sampel AlertCallbacks menunjukkan cara menangani Task<bool> objek dan Device.BeginInvokeOnMainThread panggilan yang dikembalikan menggunakan metode panggilan balik.

Pemberitahuan dengan lambda

Sampel AlertLambdas menunjukkan cara menggunakan fungsi lambda anonim untuk penanganan Task dan Device.BeginInvokeOnMainThread panggilan.

Pemberitahuan dengan menunggu

Pendekatan yang lebih mudah melibatkan kata kunci dan await yang async diperkenalkan dalam C# 5. Sampel AlertAwait menunjukkan penggunaannya.

Pemberitahuan tanpa apa-apa

Jika metode asinkron mengembalikan Task daripada Task<TResult>, maka program tidak perlu menggunakan salah satu teknik ini jika tidak perlu tahu kapan tugas asinkron selesai. Sampel NothingAlert menunjukkan ini.

Menyimpan setelan program secara asinkron

Sampel SaveProgramChanges menunjukkan penggunaan SavePropertiesAsync metode Application untuk menyimpan pengaturan program saat berubah tanpa mengesampingkan OnSleep metode .

Timer independen platform

Dimungkinkan untuk menggunakan Task.Delay untuk membuat timer independen platform. Sampel TaskDelayClock menunjukkan ini.

Input/output file

Secara tradisional, namespace .NET System.IO telah menjadi sumber dukungan I/O file. Meskipun beberapa metode dalam namespace layanan ini mendukung operasi asinkron, sebagian besar tidak. Namespace layanan juga mendukung beberapa panggilan metode sederhana yang melakukan fungsi I/O file canggih.

Kabar baik dan kabar buruk

Semua platform yang didukung oleh Xamarin.Forms penyimpanan lokal aplikasi dukungan - penyimpanan yang bersifat pribadi untuk aplikasi.

Pustaka Xamarin.iOS dan Xamarin.Android menyertakan versi .NET yang telah disesuaikan secara tegas oleh Xamarin untuk kedua platform ini. Ini termasuk kelas dari System.IO yang dapat Anda gunakan untuk melakukan I/O file dengan penyimpanan lokal aplikasi di dua platform ini.

Namun, jika Anda mencari kelas-kelas ini System.IO di Xamarin.Forms PCL, Anda tidak akan menemukannya. Masalahnya adalah bahwa Microsoft sepenuhnya mengubah I/O file untuk Windows Runtime API. Program yang menargetkan Windows 8.1, Windows Telepon 8.1, dan Platform Windows Universal tidak digunakan System.IO untuk I/O file.

Ini berarti Anda harus menggunakan (pertama kali DependencyService dibahas dalam Bab 9. Panggilan API khusus platform untuk mengimplementasikan I/O file.

Catatan

Libaries Kelas Portabel telah diganti dengan pustaka .NET Standard 2.0, dan .NET Standard 2.0 mendukung System.IO jenis untuk semua Xamarin.Forms platform. Tidak perlu lagi menggunakan DependencyService untuk sebagian besar tugas I/O file. Lihat Penanganan File untuk Xamarin.Forms pendekatan yang lebih modern untuk file I/O.

Bidikan pertama pada I/O file lintas platform

Sampel TextFileTryout mendefinisikan IFileHelper antarmuka untuk I/O file, dan implementasi antarmuka ini di semua platform. Namun, implementasi Windows Runtime tidak berfungsi dengan metode dalam antarmuka ini karena metode I/O file Windows Runtime tidak sinkron.

Mengakomodasi I/O file Windows Runtime

Program yang berjalan di bawah Windows Runtime menggunakan kelas di Windows.Storage namespace layanan dan Windows.Storage.Streams untuk I/O file, termasuk penyimpanan lokal aplikasi. Karena Microsoft menentukan bahwa setiap operasi yang membutuhkan lebih dari 50 milidetik harus asinkron untuk menghindari pemblokiran utas UI, metode I/O file ini sebagian besar asinkron.

Kode yang menunjukkan pendekatan baru ini akan berada di pustaka sehingga dapat digunakan oleh aplikasi lain.

Pustaka khusus platform

Sangat menguntungkan untuk menyimpan kode yang dapat digunakan kembali di pustaka. Ini jelas lebih sulit ketika potongan kode yang dapat digunakan kembali berbeda untuk sistem operasi yang sama sekali berbeda.

Solusi Xamarin.FormsBook.Platform menunjukkan satu pendekatan. Solusi ini berisi tujuh proyek yang berbeda:

Semua proyek platform individual (dengan pengecualian Xamarin.FormsBook.Platform.WinRT) memiliki referensi ke Xamarin.FormsBook.Platform. Ketiga proyek Windows memiliki referensi ke Xamarin.FormsBook.Platform.WinRT.

Semua proyek berisi metode statis Toolkit.Init untuk memastikan bahwa pustaka dimuat jika tidak direferensikan secara langsung oleh proyek dalam Xamarin.Forms solusi aplikasi.

Proyek Xamarin.FormsBook.Platform berisi antarmuka baru IFileHelper . Semua metode sekarang memiliki nama dengan Async akhiran dan objek pengembalian Task .

Proyek Xamarin.FormsBook.Platform.WinRT berisi FileHelper kelas untuk Windows Runtime.

Proyek Xamarin.FormsBook.Platform.iOS berisi FileHelper kelas untuk iOS. Metode ini sekarang harus asinkron. Beberapa metode menggunakan versi metode asinkron yang ditentukan dalam StreamWriter dan StreamReader: WriteAsync dan ReadToEndAsync. Yang lain mengonversi hasil menjadi Task objek menggunakan FromResult metode .

Proyek Xamarin.FormsBook.Platform.Android berisi kelas serupa FileHelper untuk Android.

Proyek Xamarin.FormsBook.Platform juga berisi FileHelper kelas yang memudahkan penggunaan DependencyService objek.

Untuk menggunakan pustaka ini, solusi aplikasi harus menyertakan semua proyek dalam Xamarin.Formssolusi Book.Platform , dan setiap proyek aplikasi harus memiliki referensi ke pustaka yang sesuai di Xamarin.FormsBook.Platform.

Solusi TextFileAsync menunjukkan cara menggunakan Xamarin.Formspustaka Book.Platform . Masing-masing proyek memiliki panggilan ke Toolkit.Init. Aplikasi menggunakan fungsi I/O file asinkron.

Menyimpannya di latar belakang

Metode dalam pustaka yang melakukan panggilan ke beberapa metode asinkron — seperti WriteFileAsync metode dan ReadFileASync di kelas Windows Runtime FileHelper — dapat dibuat agak lebih efisien dengan menggunakan ConfigureAwait metode untuk menghindari beralih kembali ke utas antarmuka pengguna.

Jangan blokir utas UI!

Terkadang menggoda untuk menghindari penggunaan ContinueWith atau await dengan menggunakan Result properti pada metode . Ini harus dihindari untuk itu dapat memblokir utas UI atau bahkan menggantung aplikasi.

Metode Anda sendiri yang dapat ditunggu

Anda dapat menjalankan beberapa kode secara asinkron dengan meneruskannya ke salah Task.Run satu metode. Anda dapat memanggil Task.Run dalam metode asinkron yang menangani beberapa overhead.

Berbagai Task.Run pola dibahas di bawah ini.

Set Mandelbrot dasar

Untuk menggambar set Mandelbrot secara real time, Xamarin.Forms. Pustaka Toolkit memiliki struktur yang Complex mirip dengan yang ada di System.Numerics namespace.

Sampel MandelbrotSet memiliki CalculateMandeblotAsync metode dalam file code-behind yang menghitung set Mandelbrot hitam-putih dasar dan menggunakannya BmpMaker pada bitmap.

Menandai kemajuan

Untuk melaporkan kemajuan dari metode asinkron, Anda dapat membuat instans Progress<T> kelas dan menentukan metode asinkron Anda untuk memiliki argumen jenis IProgress<T>. Ini ditunjukkan dalam sampel MandelbrotProgress.

Membatalkan pekerjaan

Anda juga dapat menulis metode asinkron agar dapat dibatalkan. Anda mulai dengan kelas bernama CancellationTokenSource. Properti Token adalah nilai jenis CancellationToken. Ini diteruskan ke fungsi asinkron. Program memanggil Cancel metode CancellationTokenSource (umumnya sebagai respons terhadap tindakan oleh pengguna) untuk membatalkan fungsi asinkron.

Metode asinkron dapat secara berkala memeriksa IsCancellationRequested properti dan keluar jika properti adalah true, atau hanya memanggil ThrowIfCancellationRequested metode , dalam hal ini metode berakhir dengan OperationCancelledExceptionCancellationToken .

Sampel MandelbrotCancellation menunjukkan penggunaan fungsi yang dapat dibatalkan.

An MVVM Mandelbrot

Sampel MandelbrotXF memiliki antarmuka pengguna yang lebih luas, dan sebagian besar didasarkan pada kelas MandelbrotModel dan MandelbrotViewModel :

Cuplikan layar tiga mandelbrot X F

Kembali ke web

Kelas WebRequest yang digunakan dalam beberapa sampel menggunakan protokol asinkron kuno yang disebut Model Pemrograman Asinkron atau APM. Anda dapat mengonversi kelas tersebut ke protokol TAP modern menggunakan salah FromAsync satu metode di TaskFactory kelas . Sampel ApmToTap menunjukkan hal ini.