Что создавать / закрывать по отношению к индивидуальному запросу: ChannelFactory или созданный Channel? - PullRequest
1 голос
/ 16 февраля 2012

Я занимаюсь рефакторингом большой программы, которая выполняет межпроцессное взаимодействие через wcf. Поскольку клиент имеет прямой доступ к интерфейсу службы, для создания каналов используется канал, поэтому дополнительные заглушки службы клиента не требуются. Связь состоит из множества больших сообщений, которые запрашиваются с высокой частотой (в настоящее время используется NetTcpBinding, я рассматриваю переход на NetNamedPipeBinding).

Мой вопрос касается разницы между созданием / закрытием канала и созданием / закрытием канала. Чтобы быть более точным: Channelfactory создает канал. Теперь в отношении отдельного запроса: должен ли я создать и закрыть фабрику каналов, а вместе с этим и канал в отношении отдельного запроса (см. Решение № 2), или это более безопасно / лучше с точки зрения производительности, только создавать / закройте канал относительно отдельного запроса и оставьте канал открытым для нескольких запросов (см. решение № 1).

1)

//set up the channel factory right when I start the whole applicaton
ChannelFactory<IMyService> cf = new ChannelFactory<IMyService>();

//call this trillion of times over time period of hours whenever I want to make a request to the service; channel factory stays open for the whole time
try
{
    IMyService myService = cf.CreateChannel();
    var returnedStuff = myService.DoStuff();
    ((IClientChannel)myService).Close();
}
catch ...

//close the channel factory when I stop the whole application
cf.Close();

2)

//call this trillion of times over time period of hours whenever I want to make a request to the service
try
{
    ChannelFactory<IMyService> cf = new ChannelFactory<IMyService>();
    IMyService myService = cf.CreateChannel();
    var returnedStuff = myService.DoStuff();
    cf.Close();
}
catch ...

Каковы практические различия? Как правильно это сделать? Есть ли еще лучшие альтернативы?

Ответы [ 3 ]

2 голосов
/ 18 декабря 2012

Создание фабрики каналов может занять до 70 мс (в приложении, над которым я работаю). Создание каналов (по сравнению с существующей фабрикой каналов сравнительно быстро). Если ваш клиент обычно связывается с хостом, используя те же учетные данные, вы должны рассмотреть возможность кэширования канала для каждого используемого интерфейса службы. Вы увидите значительное улучшение производительности, если вы сделаете это. В вашем вопросе это будет более тесно связано со вторым вариантом, который вы описали.

Дарин Дамитров сделал интересный пост на эту тему здесь: -

создание WCF ChannelFactory

0 голосов
/ 23 февраля 2012

Не прямой ответ на мой первоначальный вопрос, но я видел, что в ChannelFactory есть статический метод CreateChannel, который можно использовать для создания каналов. Теперь я использую этот метод для создания каналов, и в результате мне больше не нужно иметь дело с экземпляром Channelfactory. Поэтому я создаю клиентский канал перед каждым запросом со статическим фабричным методом и затем закрываю его (канал).

0 голосов
/ 16 февраля 2012

Согласно http://www.danrigsby.com/blog/index.php/2008/02/26/dont-wrap-wcf-service-hosts-or-clients-in-a-using-statement/

способ, которым вы должны сделать это:

ChannelFactory<IMyService> channelFactory = null;
try
{
    channelFactory =
        new ChannelFactory<IMyService>();
    channelFactory.Open();

    // Do work...

    channelFactory.Close();
}
catch (CommunicationException)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
}
catch (TimeoutException)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
}
catch (Exception)
{
    if (channelFactory != null)
    {
        channelFactory.Abort();
    }
    throw;
}

Основная причина этого заключается в том, что вы вызываете Dispose () для ChannelFactory, который, в свою очередь, вызывает Close(), который может вызвать исключение, если базовый канал находится в прерванном состоянии.

...