2

这是我的服务器应用程序代码:

[ServiceContract]
public interface IFirst
{
    [OperationContract]
    void First();
}

[ServiceContract]
public interface ISecond
{
    [OperationContract]
    void Second();
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class Service : IFirst, ISecond
{
    static int count = 0;
    int serviceID;

    public Service()
    {
        serviceID = ++count;

        Console.WriteLine("Service {0} created.", serviceID);
    }

    public void First()
    {
        Console.WriteLine("First function. ServiceID: {0}", serviceID);
    }

    public void Second()
    {
        Console.WriteLine("Second function. ServiceID: {0}", serviceID);
    }
}

class Server
{
    static void Main(string[] args)
    {
        ServiceHost host = new ServiceHost(typeof(Service), new Uri("net.tcp://localhost:8000"));
        NetTcpBinding binding = new NetTcpBinding();
        host.AddServiceEndpoint(typeof(IFirst), binding, "");
        host.AddServiceEndpoint(typeof(ISecond), binding, "");
        host.Open();

        Console.WriteLine("Successfully opened port 8000.");
        Console.ReadLine();          
        host.Close();
    }
}

和客户:

class Client
{
    static void Main(string[] args)
    {
        ChannelFactory<IFirst> firstFactory = new ChannelFactory<IFirst>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000"));
        IFirst iForst = firstFactory.CreateChannel();
        iForst.First();

        ChannelFactory<ISecond> secondFactory = new ChannelFactory<ISecond>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000"));
        ISecond iSecond = secondFactory.CreateChannel();
        iSecond.Second();

        Console.ReadLine();

    }
}

当我运行它时,我得到输出:

Successfully opened port 8000.
Service 1 created.
First function. ServiceID: 1
Service 2 created.
Second function. ServiceID: 2

在我的例子中,服务器创建了两个服务实例。我想要做的是为 First 所做的同一个 Service 实例调用 Second 函数。

4

3 回答 3

2

你可以做两件事:

移动 Second 到 IFirst 所以

public interface IFirst
{
    [OperationContract]
    void First();

    [OperationContract]
    void Second();
}

或者为服务实例使用单例

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
class Service : IFirst, ISecond
{
...
}
于 2011-12-14T12:19:44.317 回答
1

将你的行为改变为单身

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

当您使用InstanceContextMode.PerSession这意味着a session为每个服务创建服务时client,您正在尝试从两个客户端连接到服务,这就是它创建两个服务实例的原因

通过将其更改为InstanceContextMode.Single仅一个 Service 实例将为您的两个客户提供服务。

来自MSDN

System.ServiceModel.InstanceContext管理通道和用户定义的服务对象之间的关联。使用带有 ServiceBehaviorAttribute.InstanceContextMode 属性的 InstanceContextMode 枚举来指定 InstanceContext 对象的生命周期。可以为每个调用、每个会话创建一个新的 InstanceContext 对象,或者指定将 InstanceContext 对象绑定到单个服务对象。 Single 值指定应在服务的生命周期内使用单个 InstanceContext 对象。

于 2011-12-14T12:23:34.877 回答
0

我知道帖子很旧,但对其他人来说。

您可以做的是将您的 IFirst 和 ISecond 合并到 ICombinedService 中。然后,您将在您的客户端中创建一个通道 - 这意味着将创建您的服务主机会话的单个实例。

在您当前的代码中,您正在为 IFirst 和 ISecond 创建一个连接 [这些是您创建的两个会话实例。]

IFirst iForst = firstFactory.CreateChannel(); // 第一个会话创建!

ISecond iSecond = secondFactory.CreateChannel(); //第二个会话创建!

要改变这种行为,您需要将服务组合成一个服务;并且可以对此进行每次会话调用。

class Client
{
    static void Main(string[] args)
    {
        ChannelFactory<ICombinedFirstSecond> combinedFactory = new ChannelFactory<ICombinedFirstSecond>(new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:8000"));
        ICombinedFirstSecond iCombinedFirstSecond = combinedFactory.CreateChannel();
        iCombinedFirstSecond.First();
        iCombinedFirstSecond.Second();

        Console.ReadLine();

    }
}

这就是我认为您真正想要的,而不是单例服务。

于 2015-11-02T17:36:06.477 回答