Saya memiliki kode yang membuat token pembatalan
public partial class CardsTabViewModel : BaseViewModel
{
public CancellationTokenSource cts;
public async Task OnAppearing()
{
cts = new CancellationTokenSource(); // << runs as part of OnAppearing()
Kode yang menggunakannya:
await GetCards(cts.Token);
public async Task GetCards(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
await CheckAvailability();
}
}
dan kode yang kemudian membatalkan Token Pembatalan ini jika pengguna menjauh dari layar tempat kode di atas berjalan:
public void OnDisappearing()
{
cts.Cancel();
Mengenai pembatalan, apakah ini cara yang benar untuk membatalkan token ketika sedang digunakan dalam Tugas?
Secara khusus saya memeriksa pertanyaan ini:
Penggunaan properti IsCancellationRequested?
dan itu membuat saya berpikir bahwa saya tidak melakukan pembatalan dengan cara yang benar atau mungkin dengan cara yang dapat menyebabkan pengecualian.
Juga, dalam hal ini setelah saya membatalkan maka haruskah saya melakukan cts.Dispose ()?
c#
xamarin
xamarin.forms
Alan2
sumber
sumber
Jawaban:
CancellationTokenSource.Cancel()
adalah cara yang valid untuk memulai pembatalan.Polling
ct.IsCancellationRequested
menghindari lemparanOperationCanceledException
. Karena pemungutan suara, itu membutuhkan iterasi dari loop untuk menyelesaikan sebelum akan menanggapi permintaan pembatalan.Jika
GetViewablePhrases()
danCheckAvailability()
dapat dimodifikasi untuk menerima aCancellationToken
, ini dapat membuat pembatalan lebih cepat untuk merespons, dengan mengorbankanOperationCanceledException
membuang."Haruskah aku melakukan cts. Mengapa ()?" bukankah itu mudah ...
Lebih merupakan pedoman daripada aturan.
Task
itu sendiri sekali pakai, namun hampir tidak pernah langsung dibuang dalam kode.Ada kasus-kasus (ketika
WaitHandle
atau penangan panggilan balik digunakan) di mana membuangcts
akan membebaskan sumber daya / menghapus root GC yang sebaliknya hanya akan dibebaskan oleh Finalizer. Ini tidak berlaku untuk kode Anda sebagaimana adanya tetapi mungkin di masa depan.Menambahkan panggilan ke
Dispose
setelah membatalkan akan menjamin bahwa sumber daya ini segera dibebaskan dalam versi kode yang akan datang.Namun, Anda harus menunggu kode yang digunakan
cts
untuk menyelesaikan sebelum menelepon membuang, atau memodifikasi kode untuk menanganiObjectDisposedException
dari penggunaancts
(atau tokennya) setelah dibuang.sumber
CancellationToken
parameter), Anda dapat membuangWaitHandle
sementara utas lainnya sedang aktif menunggu di atasnya :(Dispose
dariOnDisappearing
.Cancel
...Cancel
dilakukan adalah timer internal (jika digunakan).Secara umum saya melihat penggunaan yang wajar dari Batalkan Token dalam kode Anda, tetapi menurut Pola Tugas Async kode Anda mungkin tidak segera dibatalkan.
Untuk segera merespons, kode pemblokiran juga harus dibatalkan
Terserah Anda jika Anda harus Buang, jika ada banyak sumber daya memori yang dicadangkan dalam kode terputus, Anda harus melakukannya.
sumber
Saya akan merekomendasikan Anda untuk melihat pada salah satu kelas .net untuk sepenuhnya memahami cara menangani metode menunggu dengan CanncelationToken, saya mengambil SeamaphoreSlim.cs
Anda juga dapat melihat seluruh kelas di sini, https://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,6095d9030263f169
sumber