Is it possible to convert from Task<(string,object)> to Task<string>? I have a method that receive Task<string> as argument, but from another method returning type I am getting Task<(string,object)>.
3 Answers
ContinueWith converts a Task<T> to Task<U>, using the given Func<Task<T>, U>:
Task<(string, object)> tupleTask = MethodThatReturnsTupleTask();
Task<string> stringTask = tupleTask.ContinueWith(tuple => tuple.Result.Item1);
MethodThatAcceptsStringTask(stringTask);
3 Comments
Theodor Zoulias
I don't think that Stephen Cleary will like your approach. 😃
Sweeper
@TheodorZoulias that’s what I get for thinking of tasks as functors! I ignored a lot of the details and jumped to conclusions.
Theodor Zoulias
Yeap, the
ContinueWith method is too primitive, and too cumbersome to work with. Honestly it's not a well made mechanism. In case the tupleTask fails, the stringTask will contain a nested AggregateException, which will make the error handling a real mess.You could use LINQ to Tasks:
Task<(string, object)> task1 = GetStuffAsync();
Task<string> task2 = task1.Select(value => value.Item1);
Here is the Select operator:
public static async Task<T2> Select<T1, T2>(this Task<T1> source, Func<T1, T2> selector)
{
return selector(await source);
}
A complete Linq-to-Tasks "suite" can be found here: LinqToTasks.cs. It is part of the ParallelExtensionsExtras package. Its implementation predates async/await, so it is based on the primitive ContinueWith method, with all that entails (poor exception behavior etc).