How to get effect of Task.WhenAny for a Task and CancellationToken?

astrowalker

I have interactive task which in "worst" scenario is not executed at all, thus it is represented by TaskCompletionSource.

I would like to wait for either this task completes, or token which I received is cancelled -- whichever happens first. Perfect tool for such job would be Task.WhenAny, the only problem is it takes only tasks, and I have one Task and one CancellationToken.

How to wait (asynchronously, like Task.WhenAny) for the first event triggered -- completed task, or cancelled token?

async Task MyCodeAsync(CancellationToken token)
{
  var tcs = new TaskCompletionSource<UserData>(); // represents interactive part

  await Task.WhenAny(tcs.Task, token); // imaginary call

  UserData data = tcs.Task.Result; // user interacted, let's continue
  ...
}

I don't create/manage token, so I cannot change it. I have to deal with it.

Update: For such particular case one could use Register method on token to cancel the TaskCompletionSource. For more general method please see Matthew Watson answer.

Theodor Zoulias

Here is an extension method that transforms a CancellationToken to a Task or Task<TResult>. The returned task will complete as cancelled immediately after the CancellationToken receives a cancellation request.

static class CancellationTokenExtensions
{
    public static Task AsTask(this CancellationToken token)
    {
        return new Task(() => throw new InvalidOperationException(), token);
    }

    public static Task<TResult> AsTask<TResult>(this CancellationToken token)
    {
        return new Task<TResult>(() => throw new InvalidOperationException(), token);
    }
}

Usage example. Just await any task:

await Task.WhenAny(tcs.Task, token.AsTask());

...or await and get the result in the same line as well:

var data = await Task.WhenAny(tcs.Task, token.AsTask<UserData>()).Unwrap();

The InvalidOperationException is thrown just in case, to ensure that the task of the CancellationToken will never run to completion. Its Status can only be Created, Canceled or Faulted.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

task.Wait(CancellationToken)をawaitステートメントに変換する方法は?

分類Dev

When does Task.Run(Action, CancellationToken) throw TaskCanceledException?

分類Dev

How to reset luigi task status?

分類Dev

How to cancel a Task using CancellationToken?

分類Dev

How do I run a mix task from within a mix task?

分類Dev

Could not get unknown property for task in Gradle?

分類Dev

Task.WhenAny-タスクがキャンセルされました

分類Dev

How to get arguments passed to the celery's task?

分類Dev

How to get Task ID from within ECS container?

分類Dev

Task.WhenAny ContinueWith:引数を取得しますか?

分類Dev

Task.Delay didn’t get canceled?

分類Dev

How to get reason for failure of a previous task in vsts CI build

分類Dev

辞書を使用したTask.WhenAnyの使用

分類Dev

How to change the parameters for a task with known task and tasklist ids

分類Dev

How to get task id from celery in case of scheduled tasks (beat)

分類Dev

Using a CancellationToken to cancel a task without explicitly checking within the task?

分類Dev

Task.WhenAny for a Task and CancellationTokenの効果を得る方法は?

分類Dev

How to get the queue that originated a task execution from Celery

分類Dev

Is there any way to get google cloud task status?

分類Dev

await Task.WhenAny()を使用して例外を無視する

分類Dev

How to schedule a task with airflow

分類Dev

How do Windows task scheduler recognise if the task fails

分類Dev

How to yield return item when doing Task.WhenAny

分類Dev

Task.RunSynchronously()はCancellationTokenを気にしません

分類Dev

Salesforce query to get task's comment

分類Dev

how to run setuid task properly?

分類Dev

Task.WhenAny(障害のないタスクの場合)

分類Dev

How to rescue this task?

分類Dev

C#でTask.delayのcancellationToken.cancelを処理する方法は?

Related 関連記事

  1. 1

    task.Wait(CancellationToken)をawaitステートメントに変換する方法は?

  2. 2

    When does Task.Run(Action, CancellationToken) throw TaskCanceledException?

  3. 3

    How to reset luigi task status?

  4. 4

    How to cancel a Task using CancellationToken?

  5. 5

    How do I run a mix task from within a mix task?

  6. 6

    Could not get unknown property for task in Gradle?

  7. 7

    Task.WhenAny-タスクがキャンセルされました

  8. 8

    How to get arguments passed to the celery's task?

  9. 9

    How to get Task ID from within ECS container?

  10. 10

    Task.WhenAny ContinueWith:引数を取得しますか?

  11. 11

    Task.Delay didn’t get canceled?

  12. 12

    How to get reason for failure of a previous task in vsts CI build

  13. 13

    辞書を使用したTask.WhenAnyの使用

  14. 14

    How to change the parameters for a task with known task and tasklist ids

  15. 15

    How to get task id from celery in case of scheduled tasks (beat)

  16. 16

    Using a CancellationToken to cancel a task without explicitly checking within the task?

  17. 17

    Task.WhenAny for a Task and CancellationTokenの効果を得る方法は?

  18. 18

    How to get the queue that originated a task execution from Celery

  19. 19

    Is there any way to get google cloud task status?

  20. 20

    await Task.WhenAny()を使用して例外を無視する

  21. 21

    How to schedule a task with airflow

  22. 22

    How do Windows task scheduler recognise if the task fails

  23. 23

    How to yield return item when doing Task.WhenAny

  24. 24

    Task.RunSynchronously()はCancellationTokenを気にしません

  25. 25

    Salesforce query to get task's comment

  26. 26

    how to run setuid task properly?

  27. 27

    Task.WhenAny(障害のないタスクの場合)

  28. 28

    How to rescue this task?

  29. 29

    C#でTask.delayのcancellationToken.cancelを処理する方法は?

ホットタグ

アーカイブ