WCF ChannelFactory и кэширование каналов в клиентском приложении ASP.NET

StackOverflow https://stackoverflow.com/questions/1825990

Вопрос

Я создаю серию служб WCF, которые будут использоваться более чем одним приложением.По этой причине я пытаюсь определить общую библиотеку для доступа к службам WCF.

Зная, что каждый запрос на обслуживание, сделанный разными пользователями, должен использовать другой канал, я думаю, что нужно кэшировать канал для каждого запроса (HttpContext.Current.Items) и кэшируйте ChannelFactory, используемый для создания канала для каждого приложения (HttpApplication.Items), так как я могу создать более одного канала с одним и тем же ChannelFactory.

Однако у меня есть вопрос относительно этого механизма кэширования, когда дело доходит до закрытия ChannelFactory и Channel.

  1. Нужно ли мне закрывать канал после его использования, в конце запроса, или можно оставить его там закрытым (?), когда контекст этого запроса умрет?
  2. А как насчет ChannelFactory?Поскольку каждый канал связан с создавшей его ChannelFactory, безопасно ли сохранять одну и ту же ChannelFactory в течение всего процесса приложения (AppDomain)?

Это код, который я использую для управления этим:

public class ServiceFactory
{
    private static Dictionary<string, object> ListOfOpenedChannels
    {
        get
        {
            if (null == HttpContext.Current.Items[HttpContext.Current.Session.SessionID + "_ListOfOpenedChannels"])
            {
                HttpContext.Current.Items[HttpContext.Current.Session.SessionID + "_ListOfOpenedChannels"] = new Dictionary<string, object>();
            }

            return (Dictionary<string, object>)HttpContext.Current.Items[HttpContext.Current.Session.SessionID + "_ListOfOpenedChannels"];
        }
        set
        {
            HttpContext.Current.Items[HttpContext.Current.Session.SessionID + "_ListOfOpenedChannels"] = value;
        }
    }

    public static T CreateServiceChannel<T>()
    {
        string key = typeof(T).Name;

        if (ListOfOpenedChannels.ContainsKey(key))
        {
            return (T)ListOfOpenedChannels[key];
        }
        else
        {
            ChannelFactory<T> channelF = new ChannelFactory<T>("IUsuarioService");
            T channel = channelF.CreateChannel();
            ListOfOpenedChannels.Add(key, channel);
            return channel;
        }
    }
}

Спасибо!

Это было полезно?

Решение

В идеале закройте канал, как только закончите с ним.Это вернет его в пул каналов, чтобы его мог использовать другой рабочий поток.

Да, фабрика каналов (дорогой бит) может оставаться на протяжении всего срока службы приложения.


Обновлять

Начиная с .Net 4.5 есть встроенные параметры кэширования для фабрик.Кэширование ChannelFactory .NET 4.5

Другие советы

Это в стороне.Почему вы используете SessionID в качестве контекстного ключа?Context.Items уникален для каждого запроса.То есть:

HttpContext.Current.Items[HttpContext.Current.Session.SessionID +"_ListOfOpenedChannels"]

должен быть функционально эквивалентен:

HttpContext.Current.Items["ListOfOpenedChannels"]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top