Reputation: 27927
I'm trying to make a Parallel Helper class (ParallelRunner
) that can be used like in the RequestService
class:
public class ParallelFunction
{
public ParallelFunction(Func<object> function)
{
Function = function;
}
public T GetResult<T>() where T : class
{
return (T) Data;
}
public Func<object> Function { get; private set; }
public object Data { private get; set; }
}
public static class ParallelRunner
{
public static void Run( IEnumerable<ParallelFunction> parallelFunctions)
{
Parallel.ForEach(parallelFunctions, f =>{f.Data = f.Function();});
}
}
public class RequestService
{
public void DoParallel()
{
var da = new RequestDataAccess();
var pf1 = new ParallelFunction(da.GetRequests);
var pf2 = new ParallelFunction(da.GetRequestAnswers);
ParallelRunner.Run(new List<ParallelFunction> { pf1, pf2 });
var requests = pf1.GetResult<List<Request>>();
var answers = pf2.GetResult<List<RequestAnswer>>();
}
}
what I really would love to have was a generic ParallelFunction Class like that:
public class ParallelFunction<T> where T : class
{
public ParallelFunction(Func<T> function)
{
Function = function;
}
public Func<T> Function { get; private set; }
public T Data { get; set; }
}
And instead of getting the Data From the GetResult<T>
that does a cast of the desired type, getting the Data from the T Data
property.
The problem is here ParallelRunner.Run(new List<ParallelFunction> { pf1, pf2 });
if ParallelFunction is with the generic i'm of course not able to add tow different types into the list.
Maybe someone have a good idea how to solve that?
Upvotes: 2
Views: 168
Reputation: 22829
IN such situations where generic types are exposed to non-generic infrastructure, I introduce an interface that is non-generic:
public class ParallelFunction<T> : IParallelFunction
{
private readonly Func<T> function;
public ParallelFunction(Func<T> function)
{
this.function = function;
}
public void CacheResult()
{
Data = function();
}
public T Data { get; private set; }
}
You see, I changed the design a bit to expose less of the stuff that the class does. The interface can expose non-generic bits "CacheResult". Your Helper can now work off the interface by invoking the Cacheresult method. Outside the helper you can still have your generic implementations.
public static class ParallelRunner
{
public static void Run(IEnumerable<IParallelFunction> parallelFunctions)
{
Parallel.ForEach(parallelFunctions, f => f.CacheResult());
}
}
Upvotes: 1
Reputation: 49208
Use a variant generic interface IParallelFunc<out T>
that ParallelFunc<T>
implements. Then, a IParallelFunc<int>
and a IParallelFunc<string>
could both be generalized to a IParallelFunc<object>
and be handled by your method.
Upvotes: 1