.net C中的Parallel.ForEach#-something I“;我失踪了?

.net C中的Parallel.ForEach#-something I“;我失踪了?,.net,.net-4.0,task-parallel-library,.net,.net 4.0,Task Parallel Library,我试图弄明白为什么我试图构建(使用TPL)的东西没有按预期工作 下面是一个场景:我有一堆服务请求类,它们通过中央服务处理器,并返回服务结果对象。有时我需要为一个“调用”执行多个(我想是2到5个)请求。所以我有这样的想法: ServiceRequestType1 Request1 = new ServiceRequestType1(); ServiceRequestType2 Request2 = new ServiceRequestType2(); ServiceRequestType3 Req

我试图弄明白为什么我试图构建(使用TPL)的东西没有按预期工作

下面是一个场景:我有一堆服务请求类,它们通过中央服务处理器,并返回服务结果对象。有时我需要为一个“调用”执行多个(我想是2到5个)请求。所以我有这样的想法:

ServiceRequestType1 Request1 = new ServiceRequestType1();
ServiceRequestType2 Request2 = new ServiceRequestType2();
ServiceRequestType3 Request3 = new ServiceRequestType3();
ServiceRequestType4 Request4 = new ServiceRequestType4();

ServiceProcessor sp = new ServiceProcessor();

ServiceResultType1 = sp.ProcessType1(Request1);
ServiceResultType2 = sp.ProcessType2(Request2);
ServiceResultType3 = sp.ProcessType3(Request3);
ServiceResultType4 = sp.ProcessType4(Request4);

// do stuff with the ServiceResult objects...
这4个请求,当在我的本地机器上同步运行时,所有的进程都非常快(通常每个不到10毫秒),即使它们正在访问数据库以获取数据。我对那场演出很满意。但随着时间的推移,随着数据库规模的增长和性能的降低,我想看看是否可以使用parallel.ForEach()在大致相同的时间内并行运行多个请求

因此,我设置如下:

ConcurrentBag<ServiceResultBase> results = new ConcurrentBag<ServiceResultBase>();

Parallel.ForEach<IServiceRequest>(request.Requests, serviceRequest =>
{
   ServiceResultBase serviceResult = ExecuteServiceRequest(serviceRequest);
   results.Add(serviceResult);
});
ConcurrentBag结果=新的ConcurrentBag();
Parallel.ForEach(request.Requests,serviceRequest=>
{
ServiceResultBase serviceResult=ExecuteServiceRequest(serviceRequest);
结果。添加(serviceResult);
});
正如我现在所测试的,问题是我得到的结果非常不一致。有时,所有请求一起运行非常好,4个请求总共执行时间<10毫秒。有时,一些请求的运行时间小于10毫秒,但其他请求的运行时间超过3000毫秒,有时一个或多个请求的运行时间将超过30000毫秒。有时一个或多个请求根本无法完成。我正在尝试调试并找到问题的根本原因,但到目前为止,很难判断问题出在哪里,以及Parallel.ForEach为什么会这样对我


在使用
.ForEach()
时,我是否应该注意一些问题或选项?我在这里读过其他一些关于TPL的文章,但与我所经历的完全不同。

这肯定与TPL无关,问题在于您用来访问数据库的库,或者数据库本身,与表/行锁相关的某种类型或并发性问题。使用SQL Profiler检查查询的执行情况,然后继续执行。

这肯定与TPL无关,问题在于您用来访问数据库的库,或者数据库本身,与表/行锁相关的某种类型或并发性问题。使用SQL Profiler检查查询的执行情况,然后从那里开始。

我已经这样做了,以确认它不是数据库。我在运行TPL代码时运行了SQL Profiler,所有查询都执行得很快(0s)。我从不锁定从使用中选择的表(NOLOCK)。我在内部使用标准ADO.NET SqlCommand和SqlDataReader对象来填充POCO对象。我将再次查看数据库代码,但我认为不是这样。ConcurrentBag扩展的类型是什么类型(如果有的话)?它来自.NET中的System.Collections.Concurrent命名空间-用于线程安全。你看,你没有很多选择。如果不是SQL Server,我很确定它也与ADO.NET无关。它不可能是TLP,所以我看到的唯一一件事是某种对象共享,这可能会造成一些瓶颈。你能用一个普通的列表来代替它,只是为了确保问题不是从那里来的,或者甚至是对这行进行评论,如果你还没有这样做,我已经这样做了,实际上是为了确认它不是数据库。我在运行TPL代码时运行了SQL Profiler,所有查询都执行得很快(0s)。我从不锁定从使用中选择的表(NOLOCK)。我在内部使用标准ADO.NET SqlCommand和SqlDataReader对象来填充POCO对象。我将再次查看数据库代码,但我认为不是这样。ConcurrentBag扩展的类型是什么类型(如果有的话)?它来自.NET中的System.Collections.Concurrent命名空间-用于线程安全。你看,你没有很多选择。如果不是SQL Server,我很确定它也与ADO.NET无关。它不可能是TLP,所以我看到的唯一一件事是某种对象共享,这可能会造成一些瓶颈。你可以用一个普通的列表来代替它,只是为了确保问题不是从那里来的,或者如果你还没有这样做的话,甚至对这行进行注释。