我有一个数据提供商类,该类以您期望的方式进行肥皂调用。我创建客户端,呼叫,关闭客户端,返回数据。我已将其列为下面的原始代码。
我正在进行一些批处理处理。我将一次处理30至40个记录。我将从另一类的循环中调用数据提供商。
我想知道我是否应该按照原始代码中显示的每个请求打开和关闭肥皂客户端,或者是否应该打开客户端一次,仅从for循环中检索数据,然后关闭退出循环后的肥皂客户端(修改了代码(。
如果您可以在每个实施方面提供利弊,我将不胜感激。我不确定是否在每个呼叫上创建和关闭客户端(如我的原始代码中(是一个昂贵的操作,还是微不足道的操作。如果我打开/关闭每个电话,我会遇到太多的开销吗?仅供参考,我正在使用的肥皂客户端不知道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();
使用相同的确切客户端实例为您的所有批次调用都可以。唯一可能引起问题的时间是,如果WCF服务本身设置了州填满会话。
您可以为WCF服务设置一个连接池,在其中,最好在使用后关闭连接(即将其返回池(。在连接池方案中,连接永远不会完全完全关闭。这种做法与数据库连接通常工作方式非常相似,在池中管理一堆连接并关闭连接,只需标记下一个请求的连接。