是否最好为每个呼叫打开和关闭WCF soap客户端,或者使用同一个客户端进行多个呼叫

时间:2017-06-05 14:17:22

标签: asp.net web-services wcf soap

我有一个数据提供程序类,它以您期望的方式进行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();

1 个答案:

答案 0 :(得分:0)

在这里使用相同的客户端实例进行所有批量调用都可以。它可能导致问题的唯一时间是WCF服务本身是否设置了一个状态满的会话。

您可以为WCF服务设置连接池,然后在使用它之后最好关闭连接(即将其返回池)。在连接池方案中,连接永远不会完全关闭。这种做法非常类似于数据库连接通常的工作方式,其中在池中管理一堆连接,关闭连接只是将下一个请求标记为可用的连接。