Mike Chaliy Mike Chaliy - 8 days ago 4
C# Question

Is this ok to derive from TPL Task to return more details from method?

My original method looks like:

string DoSomeWork();


Method
DoSomeWork
starts some work on other thread and returns execution ID (just random string). Later on I can query results by given execution ID. Main point is to make execution ID available before job will complete.

Now I want to change signature to return Task, so user can wait if he want to.

Task DoSomeWork();


At the same time I still need to return execution ID (for tracing purposes for example) and I see few options. First if
out
parameter, second is to return tuple with both execution ID and task(in C# this looks like not a best option), and third about which I actually want to ask.

What if I will create class that will derive from
Task
class:

public class ExtendedTask : Task
{
public string ExecutionID {get; set;}
}


Does this looks ok? Or it's better to decide other options?

P.S. In BCL there are some derived from Task classes.

UPDATE, seems I was not able to define this clear enouthg. But I need access to ExecutionID before job will complete and so I cannot use
Task.Result
.

Answer

I wouldn't personally extend Task<T>, I'd compose it instead. That way you don't need to worry about any APIs which only return Task<T> - you can just wrap the task. You can have a property which exposes the underlying task, and for the C# 5 async purposes you can implement the awaiter pattern on your own type - but it feels to me like creating your own derived type is likely to do more harm than good. It's mostly a gut feeling though.

Another option is to work the other way round: store your extra state in the Task.AsyncState property; that's what it's there for, after all. That way you can easily pass the task around without losing the execution context it's logically part of.