gpt4 book ai didi

c# - WCF channel 和 ChannelFactory 缓存

转载 作者:IT王子 更新时间:2023-10-29 04:38:34 25 4
gpt4 key购买 nike

所以我决定稍微提高我的 WCF 应用程序的性能,并尝试缓存 Channels 和 ChannelFactory。在开始之前,我需要解决所有这些问题中的两个问题。

1) ChannelFactory 是否应该作为单例实现?

2) 我不太确定如何缓存/重用单个 channel 。您是否有可以分享的有关如何执行此操作的示例?

可能很重要的一点是,我的 WCF 服务被部署为一个独立的应用程序,只有一个端点。

编辑:

感谢您的回复。不过我还有几个问题...

1) 我想我对应该在何处进行缓存感到困惑。我正在向我们公司的另一个部门提供使用此代码的客户端 API。此缓存是否发生在客户端?

2) 客户端 API 将用作 Silverlight 应用程序的一部分,这会改变什么吗?特别是在这种情况下有哪些缓存机制可用?

3)我对GetChannelFactory方法的设计还不是很清楚。如果我只有一项服务,是否应该只创建和缓存一个 ChannelFactory?

我仍然没有实现任何缓存功能(因为我完全不知道应该如何完成!),但到目前为止,这是我对客户端代理的实现:

namespace MyCompany.MyProject.Proxies
{
static readonly ChannelFactory<IMyService> channelFactory =
new ChannelFactory<IMyService>("IMyService");

public Response DoSomething(Request request)
{
var channel = channelFactory.CreateChannel();

try
{
Response response = channel.DoSomethingWithService(request);
((ICommunicationObject)channel).Close();
return response;
}
catch(Exception exception)
{
((ICommenicationObject)channel).Abort();
}
}
}

最佳答案

使用 ChannelFactory 创建工厂实例,然后缓存该实例。然后,您可以根据需要/期望从缓存的距离创建通信 channel 。

您是否需要多个 channel 工厂(即,是否有多个服务)?根据我的经验,这就是您将在性能方面看到最大优势的地方。创建 channel 是一项相当便宜的任务;它在一开始就设置好一切,这需要时间。

我不会缓存单个 channel - 我会创建它们,使用它们进行操作,然后关闭它们。如果缓存它们,它们可能会超时并且 channel 会出现故障,然后您将不得不中止它并创建一个新 channel 。

不确定为什么要使用单例来实现 ChannelFactory,特别是如果您要创建它并缓存它,并且只有一个端点。

稍后我会在有更多时间时发布一些示例代码。

更新:代码示例

这是我如何在工作项目中实现此功能的示例。我用了ChannelFactory<T> ,因为我正在开发的应用程序是一个包含多个服务的 n 层应用程序,并且会添加更多服务。目标是有一种简单的方法来在应用程序的每个生命周期中创建一次客户端,然后根据需要创建通信 channel 。这个想法的基础不是我的(我是从网络上的一篇文章中得到的),尽管我根据需要修改了实现。

我的应用程序中有一个静态帮助器类,在该类中我有一个字典和一个从 channelf 工厂创建通信 channel 的方法。

字典如下(对象是值,因为它将包含不同的 channel 工厂,每个服务一个)。我在示例中将“缓存”作为一种占位符 - 将语法替换为您正在使用的任何缓存机制。

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;
}
}

接下来是从工厂实例创建通信 channel 的方法。该方法首先检查工厂是否存在——如果不存在,则创建它,将其放入字典中,然后生成 channel 。否则,它只是从工厂的缓存实例中生成一个 channel 。

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;
}

我已经从我在工作中使用的示例中删除了一些示例。您可以使用此方法做很多事情 - 您可以处理多个绑定(bind)、分配用于身份验证的凭据等。它几乎是您用于生成客户端的一站式购物中心。

最后,当我在应用程序中使用它时,我通常会创建一个 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% 通常都与应用程序外部的事物有关(外部客户端或不受我们直接控制的数据源)。

如果有任何不清楚的地方或您还有其他问题,请告诉我。

关于c# - WCF channel 和 ChannelFactory 缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7841748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com