你能强制 Parallel.Invoke 使用多个线程吗?

loy*_*low 3 c# multithreading task-parallel-library

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

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

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

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

我想这归结为我的网站运行的硬件类型,我认为是虚拟机。

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

Pan*_*vos 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(); }
                });
Run Code Online (Sandbox Code Playgroud)

不过,除非发现实际的性能问题,否则不应尝试修改默认选项。您最终可能会过度使用 CPU 并导致延迟或抖动。

  • 是的,正如我之前所说的,一般最好使用默认行为,但是 OP 专门说他正在使用默认行为,不想这样做,并希望确保每个操作都有一个专用线程。虽然声明不太可能需要这样做是完全合适的,但在确实需要的情况下实际回答问题也很重要。 (3认同)
  • 这是一个很棒的答案,通常OP应该做什么,但是问题是具体询问如何保证它们在不同的线程上运行。也许您可以添加一个方法,如果他确实是您在上一段中描述的情况,那么您可以确定该方法实际上会在两个不同的线程上运行这些方法。 (2认同)