使用Parallel.Foreach时,Asp.net mvc应用程序的性能下降

时间:2015-06-02 10:19:16

标签: c# asp.net-mvc foreach task-parallel-library

我有一个asp.net mvc应用程序。在应用程序启动时,我循环遍历大量数据,并且对于集合中的每个项目,我进行网络调用以下载与该项目相关的一些数据。

最初我是在foreach循环中执行此操作,但在我的开发机器上平均需要26秒才能启动应用程序。所以我决定把它放在parallel.ForEach循环中。当我测量执行针对常规foreach循环的parallel.ForEach循环所花费的时间时,我注意到平均来说,parallel.ForEach循环执行得更好但是我的应用程序的性能在执行此操作时显着降低,最多需要5分钟才能启动起来。

当我在性能向导中检查iis进程时,我注意到使用常规的foreach循环,在执行此操作时iis总共从未超过47个线程但是使用Parallel.Foreach循环时,没有任何线程生成到达500我的机器。

我知道根据Parallel.Foreach的microsoft文档,对共享资源的调用会显着降低并行循环的性能。

所以我的问题是:

  1. 为什么它会降低这么多,是因为线程之间的上下文切换
  2. 为什么在执行循环体时会创建这么多线程。
  3. 为什么并行循环平均执行速度比常规for循环快,但整体应用程序的性能开始降级。
  4. 在进行可能很慢的网络服务调用时,如何使用或不使用并行foreach循环来实现更快的应用程序启动
  5. 在下面找到我正在做的代码

    //parallel loop version
    Parallel.ForEach(categories.SelectMany(c => c.Billers), service =>
    {
        try
        {
            if (service.PaymentItems == null || service.PaymentItems.Any())
            {                  
                service.PaymentItems = GetServiceOptions(service.Id);
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("Problem getting service options for {0}", service.Name), ex);
            }
    });
    
    //regular for loop version
    foreach (var service in categories.SelectMany(c => c.Billers))
    {
        try
        {
            if (service.PaymentItems == null || service.PaymentItems.Any())
                {
                    service.PaymentItems = GetServiceOptions(service.Id);
                }
            }
        catch (Exception ex)
        {
            _logger.Error(string.Format("Problem getting service options for {0}", service.Name), ex);
        }
    }
    

    方法GetServiceOptions处理网络调用

0 个答案:

没有答案