Корректная обработка службы WCF с использованием фабрики и служебных прокси в C#

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

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

Сервисный прокси

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;
    }
}

Сервисная Прокси Фабрика

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*));
    }

Вопросы:

Должен ли я закрыть Service Proxy после выполнения?

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

Действительно ли производительность благоприятна для генерации Service Proxy для каждого вызова? (мне кажется, это действительно тяжело, но, возможно, кто-то может доказать, что я не прав)

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

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

Заранее спасибо!

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 Вы должны быть осторожны при создании фабрик при каждом вызове, чтобы иметь лучшую производительность.

Хорошим решением было бы реализовать кэширование ChannelFactory<TChannel> свой (есть хорошая идея, как это сделать). Так что в конце в вашем ServiceProxyFactory вместо того, чтобы иметь new ChannelFactory<TChannel>(endpointName); Вы должны использовать кэшированные экземпляры, такие как CachedChannelFactory<TChannel>.GetInstance(),

Изменить: Есть еще одна хорошая статья, написанная Мишель Леру Бустаманте, которая объясняет, когда кэшировать или не кэшировать

Другие вопросы по тегам