4

我在 .aspx 页面中使用这样的任务并行库:

 Parallel.Invoke(
                new Action[]
                    {
                        () => { users= service.DoAbc(); },
                        () => { products= service.DoDef(); }
                    });

以前我每次调用都会触发一个线程,现在使用 Parallel.Invoke 时响应更快。

我应该假设 TPL 库会做最好的事情,还是有办法让我调整它以便它实际上并行调用?

我想这取决于我的网站运行的硬件类型,我相信它是一个虚拟机。

我的每个调用都会发出一个 http 请求以从 API 调用中获取结果。

4

2 回答 2

5

Parallel.Invoke 将并行运行您的方法,除非这比顺序运行它们更昂贵,或者线程池中没有可用的线程。这是一种优化,而不是问题。在正常情况下,您不应该尝试对框架进行事后猜测,而让它完成它的工作。

如果要调用一些长时间运行的 IO 绑定方法,则应考虑覆盖此行为。Parallel.Invoke 使用默认的 TaskScheduler,它使用与内核数量一样多的线程(不确定有多少)以避免 CPU 过载。如果您的操作只是等待一些 IO 或网络调用完成,这不是问题。

您可以使用 Parallel.Invoke(ParallelOptions,Action[])] 1覆盖指定最大线程数。您还可以使用ParallelOptions类来传递取消令牌或指定自定义 TaskScheduler,例如,允许您使用比默认调度程序更多的线程。

你可以像这样重写你的代码:

Parallel.Invoke(
            new ParallelOptions{MaxDegreeOfParallelism=30},
            new Action[]
                {
                    () => { users= service.DoAbc(); },
                    () => { products= service.DoDef(); }
                });

尽管如此,除非您发现实际的性能问题,否则您不应尝试修改默认选项。您最终可能会超额订阅 CPU 并导致延迟或抖动。

于 2013-05-09T14:40:53.683 回答
2

您可以启动几个任务来处理呼叫。

// Change to Task.Factory.StartNew depending on .NET version
var userTask = Task.Run(() => service.DoAbc());
var productsTask = Task.Run(() => service.DoDef());

Task.WaitAll(userTask, productsTask);

users = userTask.Result;
products = productsTask.Result;
于 2013-05-07T13:47:38.057 回答