Dibandingkan dengan kode sebelumnya untuk kelas RulyCanceler , saya ingin menjalankan kode menggunakan CancellationTokenSource
.
Bagaimana cara saya menggunakannya seperti yang disebutkan dalam Token Pembatalan , yaitu tanpa melempar / menangkap pengecualian? Bisakah saya menggunakan IsCancellationRequested
properti?
Saya mencoba menggunakannya seperti ini:
cancelToken.ThrowIfCancellationRequested();
dan
try
{
new Thread(() => Work(cancelSource.Token)).Start();
}
catch (OperationCanceledException)
{
Console.WriteLine("Canceled!");
}
tetapi ini memberikan kesalahan waktu proses pada cancelToken.ThrowIfCancellationRequested();
metode Work(CancellationToken cancelToken)
:
System.OperationCanceledException was unhandled
Message=The operation was canceled.
Source=mscorlib
StackTrace:
at System.Threading.CancellationToken.ThrowIfCancellationRequested()
at _7CancellationTokens.Token.Work(CancellationToken cancelToken) in C:\xxx\Token.cs:line 33
at _7CancellationTokens.Token.<>c__DisplayClass1.<Main>b__0() in C:\xxx\Token.cs:line 22
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Kode yang berhasil saya jalankan menangkap OperationCanceledException di utas baru:
using System;
using System.Threading;
namespace _7CancellationTokens
{
internal class Token
{
private static void Main()
{
var cancelSource = new CancellationTokenSource();
new Thread(() =>
{
try
{
Work(cancelSource.Token); //).Start();
}
catch (OperationCanceledException)
{
Console.WriteLine("Canceled!");
}
}).Start();
Thread.Sleep(1000);
cancelSource.Cancel(); // Safely cancel worker.
Console.ReadLine();
}
private static void Work(CancellationToken cancelToken)
{
while (true)
{
Console.Write("345");
cancelToken.ThrowIfCancellationRequested();
}
}
}
}
c#
multithreading
asynchronous
concurrency
synchronization
Tahan penuh
sumber
sumber
CancellationTokenSource
dengan metode async, metode yang berjalan lama dengan polling, dan menggunakan callback.Jawaban:
Anda dapat menerapkan metode kerja Anda sebagai berikut:
Itu dia. Anda selalu perlu menangani pembatalan sendiri - keluar dari metode ketika waktu yang tepat untuk keluar (sehingga pekerjaan dan data Anda dalam keadaan konsisten)
PEMBARUAN: Saya lebih suka tidak menulis
while (!cancelToken.IsCancellationRequested)
karena sering kali ada beberapa titik keluar di mana Anda dapat berhenti mengeksekusi dengan aman di seluruh badan perulangan, dan perulangan biasanya memiliki beberapa kondisi logis untuk keluar (mengulangi semua item dalam koleksi dll.). Jadi saya percaya lebih baik tidak mencampurkan kondisi itu karena mereka memiliki niat yang berbeda.Catatan peringatan tentang menghindari
CancellationToken.ThrowIfCancellationRequested()
:Komentar yang dipertanyakan oleh Eamon Nerbonne :
sumber
@Bayu_joo
Anda tidak boleh begitu saja mempercayai semua yang diposting di stackoverflow. Komentar dalam kode Jens salah, parameter tidak mengontrol apakah pengecualian dilempar atau tidak.
MSDN sangat jelas apa yang mengontrol parameter, apakah Anda sudah membacanya? http://msdn.microsoft.com/en-us/library/dd321703(v=vs.110).aspx
Nama variabel juga salah karena Cancel dipanggil
CancellationTokenSource
bukan pada token itu sendiri dan sumber mengubah status setiap token yang dikelolanya.sumber
Anda dapat membuat Tugas dengan token pembatalan, saat Anda membuka latar belakang aplikasi, Anda dapat membatalkan token ini.
Anda dapat melakukan ini di PCL https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/app-lifecycle
Solusi lain adalah Timer pengguna di Xamarin.Forms, hentikan timer saat aplikasi membuka latar belakang https://xamarinhelp.com/xamarin-forms-timer/
sumber
Anda dapat menggunakan
ThrowIfCancellationRequested
tanpa menangani pengecualian!Penggunaan
ThrowIfCancellationRequested
dimaksudkan untuk digunakan dari dalam aTask
(bukan aThread
). Saat digunakan dalam aTask
, Anda tidak harus menangani sendiri pengecualian tersebut (dan mendapatkan error Unhandled Exception). Ini akan mengakibatkan meninggalkanTask
, danTask.IsCancelled
properti akan menjadi True. Tidak perlu penanganan terkecuali.Dalam kasus khusus Anda, ubah
Thread
menjadiTask
.sumber
t.Start()
dan tidakTask.Run()
?Anda harus meneruskan
CancellationToken
ke Tugas, yang secara berkala akan memantau token untuk melihat apakah pembatalan diminta.Dalam hal ini, operasi akan berakhir saat pembatalan diminta dan
Task
akan memilikiRanToCompletion
status. Jika Anda ingin diakui bahwa tugas Anda telah dibatalkan , Anda harus menggunakanThrowIfCancellationRequested
untuk melemparkanOperationCanceledException
pengecualian.Semoga ini membantu untuk memahami lebih baik.
sumber