有没有一种方法可以有条件地运行生成匿名类型的查询

本文关键字:运行 查询 类型 有条件 一种 方法 有没有 | 更新日期: 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;
}