I'm writing a library which includes scheduling functionality (not the standard TaskScheduler
, IScheduler
...) based on .Net Tasks. I'm using TaskCompletionSource
, and Task.Status
is critical for representing the status of underlying operations, including TaskStatus.Created
, i.e. created but not yet started. I know returned Tasks should normally be hot, but for my manually controlled proxy Tasks, I really do want them initially as Created
.
Unfortunately for me, the initial status of TaskCompletionSource.Task
is WaitingForActivation
, i.e. it's already gone past Created
. Put differently, TaskCompletionSource
supports two states, but I need three states:
Question: How can I get a Task
that I can manually set to three different states? I.e. Task.Status
can be set to:
1) Created
2) One of WaitingForActivation
/WaitingForChildrenToComplete
/WaitingToRun
/Running
3) Either of RanToCompletion
/Canceled
/Faulted
The code below understandably complains about the type mismatch. I can instead wrap the Task by changing new Task<TResult>
to new Task<Task<TResult>>
, but to get back to Task<TResult>
I have to Unwrap()
it, and the unwrapped task will have status WaitingForActivation
, bringing me back to square one.
I will have a large number of these, so blocking a thread with Wait()
for each is not an option.
I have considered inheriting from Task
and overriding members (using new), but if possible it would be nice to give the library user an actual Task
instead of a DerivedTask
, especially since I present regular Tasks to also be awaited in many other places.
Ideas?
private TaskCompletionSource<TResult> tcs;
private async Task<TResult> CreateStartCompleteAsync()
{
await tcs.Task;
if (tcs.Task.IsCanceled)
{
throw new OperationCanceledException("");
}
else if // etc.
}
public ColdTaskCompletionSource()
{
tcs = new TaskCompletionSource<TResult>();
Task = new Task<TResult>(() => CreateStartCompleteAsync());
}
Errors:
* Cannot convert lambda expression to delegate type 'System.Func' because some of the return types in the block are not implicitly convertible to the delegate return type
* Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'TResult'