ASP.NET应用程序中的WCF客户端

时间:2011-07-21 06:52:59

标签: asp.net wcf

从ASP.NET应用程序访问WCF Web服务的最佳实践是什么?目前,在每个页面中我需要访问服务我有一个字段

private readonly _serviceClient = new WCFServiceClient();

并重复访问它的方法,在每次调用时关闭它并在每次状态为Faulted时创建一个新实例。但是,我不知道我是应该这样做,还是每个方法调用创建一个新实例。关于此的最佳做法是什么?

3 个答案:

答案 0 :(得分:2)

结帐Wenlong's blog。从.NET 3.5 Service Pack 1开始,扩展ClientBase的客户端代理共享一个静态的ChannelFactory实例缓存应用程序域范围。

从我测试和实验开始,ChannelFactory和Channel的创建是wcf调用初始化的最耗费资源的部分。通过使用“生成的代理”,如果您使用的是某些运行时> = .NET 3.5 Service Pack 1,您已经完成了ChannelFactory部分。我已经看到,当您的服务合同变得更大(更多方法,更多类型,更多参数等)时,创建频道会更加困难和更长。因此,我建议您保持服务合同的某种程度紧凑。

所以基本上如果你使用生成的代理,我认为缓存/共享不会给你带来性能提升。

对于同一服务的单个代码块中的连续调用,最好使用相同的服务代理实例。每次通话创建一个不是最好的主意。

答案 1 :(得分:1)

我在他的评论中做了类似于RubbleFord链接的文章,但由于我正在处理多个服务,所以我使用了ChannelFactory并在初始创建时缓存了返回的对象。然后我会根据需要创建新的频道,使用它们,然后根据需要关闭/中止。辅助方法在一个单独的DLL中(我将使用Common作为示例):

// bindingName refers to the Web.config binding section's name
public static T GetFactoryChannel<T>(string address, string bindingName)
{
    string key = typeof(T).Name;

    // OpenChannels is a property that refers to a Dictionary<string, object> holding the key and the channel factory
    if (!OpenChannels.ContainsKey(key))
    {  
        ChannelFactory<T> factory = new ChannelFactory<T>();

        factory.Endpoint.Address = new EndpointAddress(new System.Uri(address));
        factory.Endpoint.Binding = new NetTcpBinding(bindingName);

        OpenChannels.Add(key, factory);
    }

    T channel = ((ChannelFactory<T>)OpenChannels[key]).CreateChannel();

    ((IClientChannel(channel)).Open();

    return channel;
}

在我的客户端代码中,我会做这样的事情(使用Common中的帮助方法):

IMyContract myContract = Common.GetChannelFactory<IMyContract>("net.tcp://someaddress/service", "MyNetTcpBinding");

myContract.SomeMethod();

Common.CloseChannel(myContract); // handles the necessary work to close or abort the channel.

我是根据一年前在网上发布的一些文章开发的,当时我刚开始使用WCF,这对我很有帮助。存储OpenChannels字典对象(在我的情况下,使用AppDomain,因为我的大多数WCF服务都是WCF库)所以我只需要在给定应用程序的生命周期内创建一次每个通道工厂。

您可以根据需要向GetFactoryChannel方法添加任何必要的逻辑(例如,凭据或不同类型的绑定)。我还应该注意,我没有为项目添加服务引用,而是使用svcutil生成的代理文件。这是3.5,顺便说一句。

答案 2 :(得分:1)

您可以在整个应用程序中使用单一的服务提示。如果您正在使用依赖注入,那么任何IoC框架(如Unity或Spring.Net)都允许您将客户端配置为容器内的Singleton实例。您无需编写单独的代码来创建Singleton实例。