Pertanyaan Tugas dari token pembatalan?


Mengingat token pembatalan, saya ingin membuat tugas yang dapat ditunda, yang tidak pernah lengkap tetapi dapat dibatalkan. Saya membutuhkannya untuk pola seperti ini, yang IMO harusnya cukup umum:

async Task DoStuff(Task t, CancellationToken ct)
{
   // t was made from TaskCompletionSource, 
   // both t and ct are beyond my control

   Task t2 = TaskFromCancellationToken(ct);
   await Task.WhenAny(t, t2);

   // do stuff
}

Ide terbaik yang saya miliki sejauh ini adalah ini:

Task TaskFromCancelationToken(CancellationToken ct)
{
    return Task.Delay(Timeout.Infinite, ct);
}

Apakah ada cara yang lebih baik untuk membuat logika ini terjadi?


13
2017-09-07 05:32


asal


Jawaban:


Ini bukan sangat umum, tetapi itu cukup umum untuk menjadi bagian dari saya AsyncEx Perpustakaan. saya menggunakan sesuatu seperti ini:

public static Task AsTask(this CancellationToken cancellationToken)
{
    var tcs = new TaskCompletionSource<object>();
    cancellationToken.Register(() => tcs.TrySetCanceled(),
        useSynchronizationContext: false);
    return tcs.Task;
}

18
2017-09-07 11:37



Task.Delay(Timeout.Infinite, cancellationToken)

Jawaban yang Anda sarankan dalam pertanyaan Anda adalah solusi terbaik untuk pengetahuan saya. Inilah alasannya:

  • Itu aman
  • Sepotong kecil kode yang diperlukan
  • Pustaka standar

Itu Task.Delay Pendekatan ini banyak digunakan oleh banyak orang sesuai dengan pengetahuan saya, dan juga direkomendasikan di blog Microsoft. Contoh MSDN.

Mengapa menulis kode (termasuk tes) sendiri memanfaatkan TaskCompletionSource untuk mengonversi token pembatalan ke tugas? Lebih baik untuk memanfaatkan perpustakaan standar daripada menciptakan kembali roda; mereka lebih bebas bug daripada kode Anda.


7
2018-03-09 02:55