WCF ChannelFactory и кэширование каналов в клиентском приложении ASP.NET
-
22-07-2019 - |
Вопрос
Я создаю серию служб WCF, которые будут использоваться более чем одним приложением.По этой причине я пытаюсь определить общую библиотеку для доступа к службам WCF.
Зная, что каждый запрос на обслуживание, сделанный разными пользователями, должен использовать другой канал, я думаю, что нужно кэшировать канал для каждого запроса (HttpContext.Current.Items
) и кэшируйте ChannelFactory, используемый для создания канала для каждого приложения (HttpApplication.Items
), так как я могу создать более одного канала с одним и тем же ChannelFactory
.
Однако у меня есть вопрос относительно этого механизма кэширования, когда дело доходит до закрытия ChannelFactory и Channel.
- Нужно ли мне закрывать канал после его использования, в конце запроса, или можно оставить его там закрытым (?), когда контекст этого запроса умрет?
- А как насчет 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"]