So I created a task handler. I want to have it run for some predetermined guaranteed amount of time, then I want to do some of my stuff, and only then do I need the result of the handler to be awaited. Something like:
var th = TaskCreator();
th.awaitFor(5000);
//do some work
var result = await th;
So how can an async task run for a given number of seconds?
CodePudding user response:
You could use WhenAny
(docs):
var th = TaskCreator();
await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(5)), th);
//do some work
var result = await th;
This will stop awaiting when either of the tasks completes, meaning that you can then do your other work, and reawait th
at the end to wait for its completion (or just get the result if it has already completed).
If your TaskCreator
method does a lot of synchronous work before going async, you might want to first call await Task.Yield();
(docs) inside the TaskCreator
method before using the above code.
CodePudding user response:
The preferred mechanism here would be to implement cancellation in your TaskCreator
. This provides multiple benefits:
- it allows the work in
TaskCreator
to actually stop happening when the timeout has happened - it allows flexibility to future cancellation reasons
Example:
using var cs = new CancellationTokenSource();
cs.CancelAfter(TimeSpan.FromSeconds(5));
var result = await TaskCreator(cs.Token);
where your TaskCreator
would presumably look something like:
async Task<int> TaskCreator(CancellationToken cancellationToken)
and where you actually use cancellationToken
in TaskCreator
, either directly (usually via .ThrowIfCancellationRequested()
or .Register(...)
) or indirectly (passing it to downstream awaitable APIs).