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

私の場合、サーバーは Service の 2 つのインスタンスを作成します。私がやりたいことは、First が行ったのと同じ Service インスタンスに対して Second 関数を呼び出すことです。

4

3 に答える 3

2

次の 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作成されることを意味します.2つのクライアントからサービスに接続しようとしているため、サービスの2つのインスタンスを作成していますa sessionclient

InstanceContextMode.SingleService の 1 つのインスタンスのみに変更すると、両方のクライアントにサービスが提供されます。

MSDNから

System.ServiceModel.InstanceContextは、チャネルとユーザー定義のサービス オブジェクトの間の関連付けを管理します。InstanceContextMode 列挙体を ServiceBehaviorAttribute.InstanceContextMode プロパティと共に使用して、InstanceContext オブジェクトの有効期間を指定します。すべての呼び出し、すべてのセッションに対して新しい InstanceContext オブジェクトを作成するか、InstanceContext オブジェクトが単一のサービス オブジェクトにバインドされるように指定できます。 Single 値は、サービスの存続期間中に単一の InstanceContext オブジェクトを使用する必要があることを指定します。

于 2011-12-14T12:23:34.877 に答える
0

投稿が古いことは知っていますが、他の人にとっては。

できることは、IFirst と ISecond を ICombinedService に結合することです。次に、クライアントに 1 つのチャネルを作成します。つまり、サービス ホスト セッションの 1 つのインスタンスが作成されます。

現在のコードでは、IFirst と ISecond の接続を作成しています [これらは、作成した 2 つのセッション インスタンスです。]

IFirst iForst = firstFactory.CreateChannel(); // 最初のセッションが作成されました!

ISecond iSecond = secondFactory.CreateChannel(); // 2 番目のセッションが作成されました!

その動作を変更するには、サービスを 1 つのサービスに結合する必要があります。その上でセッションごとの呼び出しを行うことができます。

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 に答える