2015-11-03 4 views
0

У меня есть часть моей программы, которая отправляет мне электронное письмо и/или push-сообщение на мой iphone, когда что-то происходит. Это делается путем вызова двух отдельных служб WCF с использованием MSMQ. Я следовал за this гидом (модель 4.0), чтобы сделать его универсальным и проверять. Мне нравится создание общего канала, но мой вопрос заключается в том, что прокси-серверы и фабрики каналов действительно закрыты/расположены правильно, или если это взорвется, когда достигнет 10000 пользовательских окружений (что в конечном итоге будет). Код отлично работает в моей 50 тестовой среде пользователя.Правильная обработка обслуживания WCF с использованием заводских и сервисных прокси в C#

Поэтому, пожалуйста, просмотрите следующий код:

Service Proxy

public class ServiceProxy<TChannel> : IServiceProxy<TChannel> where TChannel : ICommunicationObject 
{ 
    private readonly TChannel InnerChannel; 

    public ServiceProxy(TChannel innerChannel) 
    { 
     this.InnerChannel = innerChannel; 
    } 

    public void Execute(Action<TChannel> operation) 
    { 
     try 
     { 
      operation(InnerChannel); 
      InnerChannel.Close(); 
     } 
     catch (CommunicationException) 
     { 
      InnerChannel.Abort(); 
     } 
     catch (TimeoutException) 
     { 
      InnerChannel.Abort(); 
     } 
     catch (Exception) 
     { 
      InnerChannel.Abort(); 
      throw; 
     } 
    } 

    public TResult Execute<TResult>(Func<TChannel, TResult> operation) 
    { 
     TResult result = default(TResult); 

     try 
     { 
      result = operation(InnerChannel); 
      InnerChannel.Close(); 
     } 
     catch (CommunicationException) 
     { 
      InnerChannel.Abort(); 
     } 
     catch (TimeoutException) 
     { 
      InnerChannel.Abort(); 
     } 
     catch (Exception) 
     { 
      InnerChannel.Abort(); 
      throw; 
     } 

     return result; 
    } 
} 

Service Proxy Factory

public class ServiceProxyFactory : IServiceProxyFactory 
{ 
    public IServiceProxy<TChannel> GetProxy<TChannel>(string endpointName) where TChannel : ICommunicationObject 
    { 
     var factory = new ChannelFactory<TChannel>(endpointName); 
     return new ServiceProxy<TChannel>(factory.CreateChannel()); 
    } 
} 

Выполнение вызова службы (без типа возвращаемого значения для простота)

public class MessageSender : IMessageSender 
{ 
    private const string PushServiceEndpoint = "PushEndpointName"; 
    private const string MailServiceEndpoint = "MailEndpointName"; 

    private readonly IServiceProxyFactory ServiceProxyFactory; 

    public MessageSender() 
    { 
     ServiceProxyFactory = new ServiceProxyFactory(); 
    } 

    public void NotifyMe(*some args*) 
    { 
     ServiceProxyFactory.GetProxy<MailServiceChannel>(MailServiceEndpoint) 
        .Execute(a => a.SendEmail(*some args*)); 
    } 

Вопросов:

Должен ли я закрыть ServiceProxy после Execute?

Разумно создать ChannelFactory каждый раз, когда я называю GetProxy(), и это должно ChannelFactory затем снова закрыть, если так?

Является ли это на самом деле производительность дружественная для создания ServiceProxy для каждого вызова? (мне кажется, это очень тяжело, но, возможно, кто-то может доказать, что я ошибаюсь).

Я оставил интерфейсы из этого сообщения, но они очень просты, и вся эта настройка с прокси-серверами и интерфейсами очень хорошо работает с модульными и интеграционными тестированиями.

Надеюсь, некоторые из вас, программирующие мастера, имеют мнение об этом и поделятся этим.

Заранее благодарен!

ответ

1

Основной эффект удара имеет создание ChannelFactory.

Создание ChannelFactory экземпляров несет некоторые накладные расходы, поскольку он включает в себя следующие операции: Построение ContractDescription дерева

Reflecting all of the required CLR types 

Constructing the channel stack 

Disposing of resources 

https://msdn.microsoft.com/en-us/library/hh314046%28v=vs.110%29.aspx

WCF команда реализовала кэширование для ClientBase<TChannel> класса, он подходит когда у вас есть автоматически созданные прокси-классы. При использовании чистых ChannelFactory вы должны быть осторожны при создании заводов на каждом вызове, чтобы иметь лучшую производительность.

Хорошим решением было бы реализовать кэширование вашего a good idea о том, как это сделать). Поэтому в конце вашего ServiceProxyFactory вместо new ChannelFactory<TChannel>(endpointName); вы должны использовать кешированные экземпляры, например CachedChannelFactory<TChannel>.GetInstance().

Edit: Существует еще одна хорошая статья, написанная Мишель Леру Бустаманте, что объясняет, когда To Cache or Not to Cache

+0

Спасибо за ваш вклад. Ваша ссылка на «хорошую идею» действительно интересная. Один вопрос: если создание channelelfactories является дорогостоящей операцией, почему бы не пропустить ChannelFactory для прокси через инсталляцию конструктора, а затем иметь прокси-сервер Service для каждой из служб? таким образом прокси-сервер службы мог бы создать канал, сделать что-то и закрыть канал ... Таким образом, у вас будет одна фабрика каналов для каждого ServiceProxy, которая создается только один раз. – ruNury

+0

Я думаю, что решение является также жизнеспособным вариантом, просто убедитесь, что вы контролируете время жизни ваших экземпляров. –

 Смежные вопросы

  • Нет связанных вопросов^_^