Reputation: 13
I have a data provider class that makes a SOAP call in the way that you would expect. I create the client, make the call, close the client, return the data. I have listed this as Original Code below.
I am doing some batch processing. I will be processing 30 to 40 records at a time. I will be calling the data provider from within a for loop from another class.
I would like to know if I should be opening and closing the SOAP client for each request as I have shown in the Original Code or if I should open the client once, only retrieve the data from within the for loop and then close the SOAP client after I exit the Loop (Modified Code).
If you can provide pros/cons on each implementation, I would appreciate it. I am not sure if creating and closing the client on each call (as in my original code) is a costly operation or if it is insignificant. Will I incur too much overhead if I open/close each call? FYI, the SOAP client I am using is not aware of ChannelFactory.
Original Code
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;
}
Called Like this
foreach (var record in records)
{
var someData = _sometDataProvider.RetrieveSomeInfo(someWayToIdentify);
}
Modified Code
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;
}
}
Called Like this
foreach (var record in records)
{
var someData = _sometDataProvider.RetrieveSomeInfo(someWayToIdentify);
}
_someDataProvider.Close();
Upvotes: 1
Views: 648
Reputation: 4637
Using the same exact client instance for all your batch calls will be OK here. The only time where it may cause an issue is if the WCF service itself sets up a state-full session.
You could setup a connection pool for your WCF service, in which then it would be best to close the connection (i.e. return it to the pool) after using it. In a connection pool scenario, a connection is never really closed completely. This practice is very similar to how a database connection works typically, where a bunch of connections are managed in a pool and closing a connection just marks the connection as usable by the next request to the pool.
Upvotes: 1