gpt4 book ai didi

c# - WCF、ServiceHost - CreateChannel,不创建新的远程实例

转载 作者:行者123 更新时间:2023-11-30 22:31:48 24 4
gpt4 key购买 nike

我有一个像这样设置的普通 WCF 服务:

private ServiceHost serviceHost = null;

protected override void OnStart(string[] args)
{
if (serviceHost != null)
serviceHost.Close();

Uri[] baseAddress = new Uri[]{
new Uri("net.pipe://localhost")};

string PipeName = "DatabaseService";

serviceHost = new ServiceHost(typeof(Kernel), baseAddress); // Kernel implements IDatabase

serviceHost.AddServiceEndpoint(typeof(IDatabase), new NetNamedPipeBinding(), PipeName);

serviceHost.Open();
}

protected override void OnStop()
{
if (serviceHost != null && serviceHost.State != CommunicationState.Closed)
{
serviceHost.Close();
serviceHost = null;
}
}

我猜从这段代码中,创建了一个“内核”实例,因为我只让这个服务运行了一次。

我像这样使用 ChannelFactory 创建一个代理对象:

pipeFactory = new ChannelFactory<IDatabase>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/DatabaseService"));
m_Database = pipeFactory.CreateChannel();

我不得不说,我的内核实例访问本地文件,因此我只获得此类的一次物理实例非常重要。我希望我的服务能够解决这个问题,但我的问题来了。

当服务正在运行并且单个 channel 已创建并处于事件状态时,第二个客户端出现并希望也创建一个 channel 。这工作正常,但如果我开始使用代理对象,则会抛出 FaultException,因为创建了我的内核类的第二个实例。

因此我猜测每次调用 CreateChannel 都会创建一个 Kernel 类的实例。

是否可以避免创建新实例并在调用 CreateChannel 时始终返回对单个内核类实例的引用?

问候,入侵

最佳答案

是的,默认情况下,WCF 使用每 session 或每调用调用约定,例如来自客户端的每个传入服务请求都会获得一个新的、单独的服务(实现)类实例。

当然,您可以使用 InstanceContextMode(PerSession 是默认设置 - 至少在支持它的绑定(bind)上 -,PerCall 推荐的最佳实践,Single 是单例)和服务上的 ConcurrencyMode 设置。

您可以在配置中或直接在您的服务类中定义它们。

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] 
public class CalculatorService : ICalculatorInstance
{
...
}

参见 MSDN documentation on WCF Sessions, Instancing and Concurrency以获得对所有细节的详尽解释。另请阅读优秀的 MSDN 杂志文章 Discover Mighty Instance Management Techniques For Developing WCF Apps由 Juval Lowy 撰写,始终是一个很好的资源!

如果您确实将服务类切换为单例 (InstanceContextMode=InstanceContextMode.Single),则需要注意两个权衡:

  • 或者您将 ConcurrencyMode 也定义为 Single,这实际上意味着一次只能处理一个请求;请求将被序列化,即如果处理请求需要相当长的时间,后续请求将不得不开始等待并可能最终超时

  • 另一种选择是将ConcurrencyMode设置为Multiple,这样您的单例服务类就可以同时处理多个请求;但这也意味着,您必须以完全线程安全的方式编写您的服务类,并且您需要同步和保护对共享数据成员的任何并发访问——这通常是非常棘手且难以实现的做正确的编程练习

关于c# - WCF、ServiceHost - CreateChannel,不创建新的远程实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9025623/

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