希望大家能就此给予指点。
我生成代码,我必须在其中调用远程资源,如网络服务或数据库。
考虑这段代码
class Parent{
IEnumerable<Child> Children;
int SumChildren() {
// note the AsParallel
return Children.AsParallel().Sum(c => c.RemoteCall());
}
}
class Child {
public int RemoteCall() {
// call some webservice. I'd like to pool these calls
// without having to rewrite the rest of this code
}
}
对于 50 个 child ,它将对服务进行 50 次调用,占用 50 倍的开销。在我现实生活中的例子中,这可能很容易就是一百万次调用,让整个事情变得扑朔迷离。
我想做的是以某种对调用线程/任务透明的方式对这些调用进行批处理。因此,它不是直接调用服务,而是调用一些中央队列(“火车站”)来批处理这些调用。
这样当它这样做时,调用任务就会阻塞。然后队列等待 X 调用累积,然后使用请求列表对远程服务进行 1 次调用。
当结果到来时,这个队列将返回值返回给正确的任务并解除阻塞。对于调用线程,所有这些都隐藏起来,看起来只是另一个函数调用。
这能做到吗? TPL 中是否有原语可以让我这样做?
它有点像 CCR,同时有很多事情在等待其他事情完成。
我当然可以重写此代码以在父类上创建请求列表,然后调用该服务。问题是我的真正问题是生成了所有这些代码。所以我将不得不“深入了解”Child.RemoteCall 的实现,这使得这一切比现在复杂得多。 Child 也可以是远程对象的代理等。如果可行的话会非常困难,我宁愿隔离这种复杂性。
希望这对某人有意义,如果没有让我知道我会详细说明。
最佳答案
您只是触及了大规模并行编程的皮毛。你需要考虑 concurrency oriented way .您正在启动 51 个作业,而不是您需要批处理的 50 个作业。额外的工作是管理 50 个工作的工作。就您需要的原语而言。
JOBHANDLE X= GetJobId();
//single job
AddJob(JOBHANLDE X,ChildJob y);
//container of jobs
AddJobs(JOBHANDLE x, ChildJobs Y);
BeginAsyncExecute(JOBHANDLE X);
WaitTillResult(JOBHANDLE X);
您需要一个在后台定义阻塞原语(超出操作系统内核提供的原语)并管理要执行的工作线程和作业的引擎,从外观上看,这是由 PLINQ 技术处理的。 PLINQ 还使用绿色线程,这很好。
您提到过您将混合使用数据库和网络服务器。因此,您的作业流程/功能必须在执行批处理之前将子级映射到正确的资源。因此,50 个 child 可能会减少到更少的可批处理 RPC 调用。
因此,您构建了作业批处理,然后对其进行了阻塞。
变得更具体将很难。但根据目前的讨论,请告诉我您遇到了什么问题。
关于c# - 如何批量远程调用数据库或服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1851831/