【发布时间】:2014-07-09 08:32:39
【问题描述】:
我在 .NET 4.5.2 上创建的 MVC 5 ASP.NET 应用程序上有一个服务层项目,它调用外部第 3 方 WCF 服务以异步获取信息。调用外部服务的原始方法如下(总共有 3 个相似,我从我的 GetInfoFromExternalService 方法中按顺序调用(注意它实际上不是这样调用的 - 只是为了说明而命名)
private async Task<string> GetTokenIdForCarsAsync(Car[] cars)
{
try
{
if (_externalpServiceClient == null)
{
_externalpServiceClient = new ExternalServiceClient("WSHttpBinding_IExternalService");
}
string tokenId= await _externalpServiceClient .GetInfoForCarsAsync(cars).ConfigureAwait(false);
return tokenId;
}
catch (Exception ex)
{
//TODO plug in log 4 net
throw new Exception("Failed" + ex.Message);
}
finally
{
CloseExternalServiceClient(_externalpServiceClient);
_externalpServiceClient= null;
}
}
这意味着当每个异步调用完成时,finally 块运行 - WCF 客户端已关闭并设置为 null,然后在发出另一个请求时更新。这工作正常,直到需要进行更改,如果用户传递的汽车数量超过 1000,我创建一个拆分函数,然后在每个 1000 的 WhenAll 中调用我的 GetInfoFromExternalService 方法 - 如下所示:
if (cars.Count > 1000)
{
const int packageSize = 1000;
var packages = SplitCarss(cars, packageSize);
//kick off the number of split packages we got above in Parallel and await until they all complete
await Task.WhenAll(packages.Select(GetInfoFromExternalService));
}
但是现在这倒塌了,好像我有 3000 辆汽车一样,对 GetTokenId 的方法调用通知了 WCF 服务,但 finally 块将其关闭,因此第二批尝试运行的 1000 辆汽车会引发异常。如果我删除 finally 块,代码可以正常工作 - 但不关闭此 WCF 客户端显然不是一个好习惯。
我曾尝试将它放在我的 if else 块之后评估 cars.count - 但是如果用户上传了例如 2000 辆汽车并且在 1 分钟内完成并运行 - 同时用户可以控制他们可以再上传 2000 个网页,或者其他用户可以上传,但它再次因异常而崩溃。
任何人都可以看到正确关闭外部服务客户端的好方法吗?
【问题讨论】:
标签: c# .net wcf asynchronous async-await