Berikut adalah beberapa solusi, dalam urutan menurun dari kebaikan umum:
1. Menggunakan default(CancellationToken)
sebagai nilai default:
Task DoAsync(CancellationToken ct = default(CancellationToken)) { … }
Secara semantik, CancellationToken.None
akan menjadi kandidat ideal untuk default, tetapi tidak dapat digunakan seperti itu karena ini bukan konstanta waktu kompilasi. default(CancellationToken)
adalah hal terbaik berikutnya karena merupakan konstanta waktu kompilasi dan didokumentasikan secara resmi sebagai padanannyaCancellationToken.None
.
2. Menyediakan metode overload tanpa CancellationToken
parameter:
Atau, jika Anda lebih suka metode kelebihan beban daripada parameter opsional (lihat ini dan pertanyaan ini tentang topik itu):
Task DoAsync(CancellationToken ct) { … }
Task DoAsync() => DoAsync(CancellationToken.None);
Untuk metode antarmuka, hal yang sama dapat dicapai dengan menggunakan metode ekstensi:
interface IFoo
{
Task DoAsync(CancellationToken ct);
}
static class Foo
{
public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}
Hal ini menghasilkan antarmuka yang lebih ramping dan mencegah pelaksana dari secara eksplisit menulis kelebihan metode penerusan.
3. Membuat parameter menjadi null dan menggunakan null
sebagai nilai default:
Task DoAsync(…, CancellationToken? ct = null)
{
… ct ?? CancellationToken.None …
}
Saya suka solusi ini paling tidak karena jenis nullable datang dengan overhead runtime kecil, dan referensi ke token pembatalan menjadi lebih bertele-tele karena operator penggabungan null ??
.
CancellationToken.None
menjadi sesuatu yang lebih dari itudefault(CancellationToken)
.