How to make the completion of TaskCompletionSource.Task
happen on specific TaskScheduler
, when I call TaskCompletionSource.SetResult
?
Currently, I'm using the idea I borrowed from this post:
static public Task<TResult> ContinueOnTaskScheduler<TResult>(
this Task<TResult> @this, TaskScheduler scheduler)
{
return @this.ContinueWith(
antecedent => antecedent,
CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously,
scheduler).Unwrap();
}
So whenever I would return TaskCompletionSource.Task
to the caller, I now return TaskCompletionSource.Task.ContinueOnTaskScheduler(scheduler)
instead.
Is it possible to somehow avoid this another level of indirection of ContinueWith
?
It would be interesting to know your goals behind this. Anyway, if you like to avoid the overhead of
ContinueWith
(which I think is quite low), you'd probably have to come up with your own version of a pattern similar toTaskCompletionSource
.It's not that complex. E.g., something like
Promise
below can be used in the same way you useTaskCompletionSource
, but would allow to provide a customTaskScheduler
for completion (disclaimer: almost untested):On a side note, this version has an override for
SetException(ExceptionDispatchInfo edi)
, so you could propagate the active exception's state from insidecatch
:It's easy to create a generic version of this, too.
There's a downside of this approach, though. A 3rd party can do
promise.Task.Run
orpromise.Task.RunSynchronously
, as theTask
is exposed in theTaskStatus.Created
state.You could add a check for that into
InvokeCompletionAction
, or you could probably hide it using nested tasks /Task.Unwrap
(although the latter would bring some overhead back).