使用 ChannelFactory 创建工厂的实例,然后缓存该实例。然后,您可以根据需要/希望从缓存的 istance 创建通信通道。
您是否需要多个渠道工厂(即是否有多种服务)?以我的经验,这就是你会看到性能的最大好处的地方。创建频道是一项相当便宜的任务。它在一开始就设置好一切,这需要时间。
我不会缓存单个频道 - 我会创建它们,将它们用于操作,然后关闭它们。如果您缓存它们,它们可能会超时并且通道将出现故障,那么您将不得不中止它并创建一个新的。
不知道为什么要使用单例来实现 ChannelFactory,特别是如果您要创建它并缓存它,并且只有一个端点。
稍后我有更多时间时会发布一些示例代码。
更新:代码示例
这是我如何为工作中的项目实施此示例的示例。我使用ChannelFactory<T>
的是 ,因为我正在开发的应用程序是一个具有多个服务的 n 层应用程序,并且会添加更多服务。目标是有一种简单的方法在应用程序的每个生命周期中创建一次客户端,然后根据需要创建通信渠道。这个想法的基础不是我的(我从网上的一篇文章中得到),尽管我根据自己的需要修改了实现。
我的应用程序中有一个静态帮助程序类,在该类中我有一个字典和一个从 channelf 工厂创建通信通道的方法。
字典如下(对象是值,因为它将包含不同的通道工厂,每个服务一个)。我在示例中将“缓存”作为一种占位符 - 用您正在使用的任何缓存机制替换语法。
public static Dictionary<string, object> OpenChannels
{
get
{
if (Cache["OpenChannels"] == null)
{
Cache["OpenChannels"] = new Dictionary<string, object>();
}
return (Dictionary<string, object>)Cache["OpenChannels"];
}
set
{
Cache["OpenChannels"] = value;
}
}
接下来是一种从工厂实例创建通信通道的方法。该方法首先检查工厂是否存在 - 如果不存在,则创建它,将其放入字典中,然后生成通道。否则,它只是从工厂的缓存实例中生成一个通道。
public static T GetFactoryChannel<T>(string address)
{
string key = typeof(T.Name);
if (!OpenChannels.ContainsKey(key))
{
ChannelFactory<T> factory = new ChannelFactory<T>();
factory.Endpoint.Address = new EndpointAddress(new System.Uri(address));
factory.Endpoint.Binding = new BasicHttpBinding();
OpenChannels.Add(key, factory);
}
T channel = ((ChannelFactory<T>)OpenChannels[key]).CreateChannel();
((IClientChannel)channel).Open();
return channel;
}
我已经从我在工作中使用的一些内容中删除了这个示例。您可以在此方法中做很多事情 - 您可以处理多个绑定、分配用于身份验证的凭据等。它几乎是您生成客户端的一站式购物中心。
最后,当我在应用程序中使用它时,我通常会创建一个通道,处理我的业务,然后关闭它(或在需要时中止它)。例如:
IMyServiceContract client;
try
{
client = Helper.GetFactoryChannel<IMyServiceContract>("http://myserviceaddress");
client.DoSomething();
// This is another helper method that will safely close the channel,
// handling any exceptions that may occurr trying to close.
// Shouldn't be any, but it doesn't hurt.
Helper.CloseChannel(client);
}
catch (Exception ex)
{
// Something went wrong; need to abort the channel
// I also do logging of some sort here
Helper.AbortChannel(client);
}
希望上面的例子能给你一些东西。我已经在生产环境中使用类似的东西大约一年了,而且效果很好。我们遇到的 99% 的问题通常都与应用程序之外的事物有关(外部客户端或不受我们直接控制的数据源)。
让我知道是否有任何不清楚或您有其他问题。