Я пытаюсь преобразовать существующее приложение .NET Remoting в WCF. Оба сервера и клиента имеют общий интерфейс, а все объекты - объекты, активированные сервером.
В мире WCF это будет похоже на создание службы для каждого вызова и использование ChannelFactory<T>
для создания прокси. Я немного борюсь с тем, как правильно создать ChannelFactory<T>
для клиента ASP.NET.
По соображениям производительности я хочу кэшировать объекты ChannelFactory<T>
и просто создавать канал каждый раз, когда я звоню в службу. В .NET remoting days использовался метод RemotingConfiguration.GetRegisteredWellknownClientTypes()
для получения коллекции клиентских объектов, которые я мог бы кэшировать. Похоже, в мире WCF нет такой вещи, хотя мне удалось получить набор конечных точек из файла конфигурации.
Теперь вот что я думаю, будет работать. Я могу создать что-то вроде этого:
public static ProxyHelper
{
static Dictionary<Type, object> lookup = new Dictionary<string, object>();
static public T GetChannel<T>()
{
Type type = typeof(T);
ChannelFactory<T> factory;
if (!lookup.ContainsKey(type))
{
factory = new ChannelFactory<T>();
lookup.Add(type, factory);
}
else
{
factory = (ChannelFactory<T>)lookup[type];
}
T proxy = factory.CreateChannel();
((IClientChannel)proxy).Open();
return proxy;
}
}
Я думаю, что вышеприведенный код будет работать, но я немного беспокоюсь о нескольких потоках, пытающихся добавить новые объекты ChannelFactory<T>
, если он не находится в поиске. Поскольку я использую .NET 4.0, я думал об использовании ConcurrentDictionary
и использовал метод GetOrAdd()
или сначала использовал метод TryGetValue()
, чтобы проверить, существует ли ChannelFactory<T>
и его не существует, а затем используйте метод GetOrAdd()
. Не уверен в производительности, хотя из методов ConcurrentDictionary.TryGetValue()
и ConcurrentDictionary.GetOrAdd()
.
Еще один второстепенный вопрос: нужно ли мне вызвать метод ChannelFactory.Close()
на каналах factory после завершения приложения ASP.NET или я могу просто позволить платформе .NET самостоятельно размещать объекты канала factory. Прокси-канал всегда будет закрыт после вызова метода службы с помощью метода ((IChannel)proxy).Close()
.