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:
DisplayAlert
Task
mengembalikan objekDisplayAlert
Task<bool>
mengembalikan objekDisplayActionSheet
Task<string>
mengembalikan objek
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:
- Xamarin.FormsBook.Platform, PCL normal Xamarin.Forms
- Xamarin.FormsBook.Platform.iOS, pustaka kelas iOS
- Xamarin.FormsBook.Platform.Android, pustaka kelas Android
- Xamarin.FormsBook.Platform.UWP, pustaka kelas Universal Windows
- Xamarin.FormsBook.Platform.WinRT, proyek bersama untuk kode yang umum untuk semua platform Windows
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 OperationCancelledException
CancellationToken
.
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
:
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.