有没有一种方法可以有条件地运行生成匿名类型的查询
本文关键字:运行 查询 类型 有条件 一种 方法 有没有 | 更新日期: 2023-09-27 17:57:29
编辑:主要解决如下问题。然而,我想知道的另一件事(为了在未来改进谷歌功能)是-你会怎么表达这个问题?我知道我的标题有点奇怪,但想不出更简洁的方式来总结它。欢迎在评论中提出建议。
假设我的工作流程涉及一个潜在的昂贵选择。在运行时,我希望能够选择是否进行这种并行。
为了更好地解释。考虑这个查询(坏代码-do-what-i-want-not-what-i-say):
void Main()
{
bool runTimeParallelOption = false; // assume this option comes from e.g. user/config
var j = Enumerable.Range(1,5);
if (runTimeParallelOption)
j = j.AsParallel();
var results = j.Select(x =>
{
Thread.Sleep(1000);
return new { Number = x, Square = x * x };
});
var sw = Stopwatch.StartNew();
foreach (var result in results)
Console.WriteLine(result.Square);
Console.WriteLine("Elapsed: : " + sw.Elapsed);
}
这里的希望是,如果设置了runTimeParallelOption
,它将使查询并行。然而,很明显(事后看来!)这不起作用,因为j的类型意味着我仍在执行IEnumerable扩展方法。
如果你不介意重构使{ Number = x, Square = x * x }
成为一流的类型,那么解决这个问题的方法是微不足道的,但这对我来说不是很有吸引力。有没有一种方法可以让我大快朵颐?
我认为这里最简单的选项是始终使用AsParallel()
。然后,如果您不想将其并行化,请添加WithDegreeOfParallelism(1)
。
受此启发,我想出了最好的办法:
void Main()
{
bool runTimeParallelOption = true; // assume this option comes from e.g. user/config
var j = Enumerable.Range(1,5);
var results = Enumerable.Empty<int>().Select(x => new { Number = (int)0, Square = (int)0 }).Take(0);
var mutate = InferredProjection(1, results.FirstOrDefault(), x => { Thread.Sleep(1000); return new { Number = x, Square = x * x }; });
var sw = Stopwatch.StartNew();
if (runTimeParallelOption)
results = j.AsParallel().Select(mutate);
else
results = j.Select(mutate);
sw.Stop();
foreach (var result in results)
Console.WriteLine(result.Square);
Console.WriteLine("Elapsed: : " + sw.Elapsed);
}
static Func<T, U> InferredProjection<T, U>(T infer1, U infer, Func<T, U> project)
{
return project;
}