我有一个WCF服务,该服务又调用其他几个Web服务。这些服务按照优先顺序排列,但并行调用。每项服务都会以真或假做出回应,并且当收到所有回复后,最可取的积极信息将返回给客户。如何在WCF服务中返回值后继续处理
但是,在此期间的任何时候,最喜欢的服务可能会以积极的方式回应。此时继续查询其他服务是没有意义的,所以我希望取消执行并将结果返回给客户端。
这一点我可以这样做:
// Use parallelOptions to store the cancellation token
ParallelOptions po = new ParallelOptions();
po.CancellationToken = cts.Token;
Parallel.ForEach<IntegrationObj>(externalServices, po, x =>
{
try
{
// Send requests
SendExternalRequest(x);
po.CancellationToken.ThrowIfCancellationRequested();
}
catch (OperationCanceledException e)
{
/// Don't throw an exception if the loop was cancelled
}
catch (Exception e)
{
LogError(e.Message);
}
});
if (positiveResponses.Count > 0) {
// Get the most preferred positive response and send it back to the client
res = positiveResponses.Where(
x => x.ID == PreferredServiceID)
.FirstOrDefault();
}
return res;
上面的代码是我的代码非常简化的版本,但本质上它会检查每个响应,看它是否是目前最优选的服务。如果是这样,它取消循环。
但是...取消这样的循环将等待已叫去完成它终止循环之前的任何服务。有一个合理的机会,任何服务都可能超时,这当然被视为负面的。如果只是其中一次,它会在我的响应时间上增加额外的10秒。
我想什么做的是下列之一:
- 返回首选服务到客户端,然后继续处理,从已经启动的服务走在了回应(这纯粹是为了记录目的,以便我知道这些服务的积极/消极比率)。
- 立即取消循环并忘记其余的响应。理想情况下,我不想这样做,因为这意味着服务可能会有积极回应,不会被记录下来,这会影响他们的偏好等级。
所以我的问题是这样的:
是我想达到什么可能?我意识到parallel.foreach可能不是这项工作的最佳工具,或者我可能无法在回复客户端后记录响应。最重要的要求是客户在获得“胜利者”时无需等待服务响应就能获得快速响应。
我到最后第二种方法。这确实意味着在决定结果后仍然会继续查询剩余的服务,但是已经胜过了Parallel.ForEach。 – Maloric 2012-04-26 14:34:41