WCF 客户端应用程序使用该 ChannelFactory<TChannel> 类创建与 WCF 服务的信道。 创建 ChannelFactory<TChannel> 实例会产生一些开销,因为它涉及以下操作:
构造 ContractDescription 树
反映所有所需的 CLR 类型
构造通道堆栈
资源的释放
为了最大程度地减少此开销,在使用 WCF 客户端代理时,WCF 可以缓存通道工厂。
小窍门
直接使用 ChannelFactory<TChannel> 类时,可以直接控制通道工厂的创建。
使用 ServiceModel 元数据实用工具工具(Svcutil.exe) 生成的 WCF 客户端代理派生自 ClientBase<TChannel>。 ClientBase<TChannel> 定义定义通道工厂缓存行为的静态 CacheSetting 属性。 缓存设置是为特定类型创建的。 例如,将 ClientBase<ITest>.CacheSettings
设置为下述定义的值之一,仅会影响类型为 ITest
的代理/ClientBase。 创建第一个代理/ClientBase 实例后,特定 ClientBase<TChannel> 对象的缓存设置是不可变的。
指定缓存行为
通过将属性设置为 CacheSetting 以下值之一来指定缓存行为。
缓存设置值 | DESCRIPTION |
---|---|
AlwaysOn | 应用域中的所有实例 ClientBase<TChannel> 都可以参与缓存。 开发人员已确定缓存没有任何不利的安全影响。 即使访问了“安全敏感”属性, ClientBase<TChannel> 缓存也不会关闭。 ClientBase<TChannel>的“安全敏感”属性包括ClientCredentials、Endpoint和ChannelFactory。 |
Default | 只有从在配置文件中定义的终结点创建的 ClientBase<TChannel> 的实例才参与应用程序域内的缓存。 在该应用域中以编程方式创建的任何实例 ClientBase<TChannel> 都不会参与缓存。 此外,只要访问 ClientBase<TChannel> 的实例的任何“安全性敏感”属性,就将为其禁用缓存。 |
AlwaysOff | 在相关应用程序域内,已对特定类型的 ClientBase<TChannel> 的所有实例关闭缓存。 |
以下代码片段演示了如何使用属性 CacheSetting 。
class Program
{
static void Main(string[] args)
{
ClientBase<ITest>.CacheSettings = CacheSettings.AlwaysOn;
foreach (string msg in messages)
{
using (TestClient proxy = new TestClient (new BasicHttpBinding(), new EndpointAddress(address)))
{
// ...
proxy.Test(msg);
// ...
}
}
}
}
// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest { }
在上述代码中,所有实例 TestClient
都将使用相同的通道工厂。
class Program
{
static void Main(string[] args)
{
ClientBase<ITest>.CacheSettings = CacheSettings.Default;
int i = 1;
foreach (string msg in messages)
{
using (TestClient proxy = new TestClient ("MyEndpoint", new EndpointAddress(address)))
{
if (i == 4)
{
ServiceEndpoint endpoint = proxy.Endpoint;
... // use endpoint in some way
}
proxy.Test(msg);
}
i++;
}
}
// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest {}
在上面的示例中,除实例 #4 之外,所有实例 TestClient
都将使用相同的通道工厂。 实例 # 4 将使用专门供其使用而创建的通道工厂。 此设置适用于特定终结点需要与同一通道工厂类型的其他终结点不同的安全设置(在本例 ITest
中)。
class Program
{
static void Main(string[] args)
{
ClientBase<ITest>.CacheSettings = CacheSettings.AlwaysOff;
foreach (string msg in messages)
{
using (TestClient proxy = new TestClient ("MyEndpoint", new EndpointAddress(address)))
{
proxy.Test(msg);
}
}
}
}
// Generated by SvcUtil.exe
public partial class TestClient : System.ServiceModel.ClientBase, ITest {}
在上面的示例中,所有实例 TestClient
都将使用不同的通道工厂。 当每个终结点具有不同的安全要求并且缓存没有意义时,这非常有用。