我有一个数据提供程序类,它以您期望的方式进行SOAP调用。我创建客户端,进行调用,关闭客户端,返回数据。我在下面将其列为原始代码。
我正在进行一些批处理。我将一次处理30到40条记录。我将从另一个类的for循环中调用数据提供程序。
我想知道我是否应该为原始代码中显示的每个请求打开和关闭SOAP客户端,或者如果我应该打开客户端一次,只检索for循环中的数据然后关闭退出循环(修改代码)后的SOAP客户端。
如果您可以在每次实施时提供优缺点,我将不胜感激。我不确定在每次调用时创建和关闭客户端(如在我的原始代码中)是一项代价高昂的操作还是无关紧要。如果我打开/关闭每个电话,是否会产生太多开销?仅供参考,我使用的SOAP客户端不知道ChannelFactory。
原始代码
public int RetrieveSomeInfo(string someWayToIdentify)
{
int result = 0;
try
{
_client = new SomeSoapClient();
var someResponse = _client.Search(someWayToIdentify);
if (someResponse.Any())
{
result = someResponse.First().SomeIntData;
}
_client.Close();
}
catch (CommunicationException e)
{
_logger.Error(e.Message, e);
_client.Abort();
}
catch (TimeoutException e)
{
_logger.Error(e.Message, e);
_client.Abort();
}
catch (Exception e)
{
_logger.Error(e.Message, e);
_client.Abort();
throw;
}
return result;
}
像这样打电话
foreach (var record in records)
{
var someData = _sometDataProvider.RetrieveSomeInfo(someWayToIdentify);
}
修改后的代码
public int RetrieveSomeInfo(string someWayToIdentify)
{
int result = 0;
try
{
//Client created through DI
if (_client == null || _client.State != System.ServiceModel.CommunicationState.Opened)
{
_client = new SomeService();
}
var someResponse = _client.Search(someWayToIdentify);
if (someResponse.Any())
{
result = someResponse.First().SomeIntData;
}
}
catch (Exception e)
{
_logger.Error(e.Message, e);
throw;
}
return result;
}
public void Close()
{
try
{
_client.Close();
}
catch (CommunicationException e)
{
_logger.Error(e.Message, e);
_client.Abort();
}
catch (TimeoutException e)
{
_logger.Error(e.Message, e);
_client.Abort();
}
catch (Exception e)
{
_logger.Error(e.Message, e);
_client.Abort();
throw;
}
}
像这样打电话
foreach (var record in records)
{
var someData = _sometDataProvider.RetrieveSomeInfo(someWayToIdentify);
}
_someDataProvider.Close();
答案 0 :(得分:0)
在这里使用相同的客户端实例进行所有批量调用都可以。它可能导致问题的唯一时间是WCF服务本身是否设置了一个状态满的会话。
您可以为WCF服务设置连接池,然后在使用它之后最好关闭连接(即将其返回池)。在连接池方案中,连接永远不会完全关闭。这种做法非常类似于数据库连接通常的工作方式,其中在池中管理一堆连接,关闭连接只是将下一个请求标记为可用的连接。