WCF服务实例的生命周期?

Edw*_*ard 7 c# wcf

在创建WCF服务的过程中,我遇到了一个对我来说不熟悉的术语.基本上在指定时InstanceContextMode我有几个选项,包括; PerSession,PerCallSingle.这是我正在学习的示例中的代码:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class EvalService : IEvalService { ...
Run Code Online (Sandbox Code Playgroud)

现在,他说这样做只会在运行时创建一个服务实例.这是什么意思?我认为,每次与Web服务建立连接时,它都被视为一个单独的实例.

对于每个请求,它是否仍然存在,这是我的服务实例?根据文档中提到的其他成员来判断,假设这是它的工作方式是否安全?

Dav*_*ter 11

根据文档:

只有一个InstanceContext对象用于所有传入呼叫,并且在调用之后不会被回收.如果服务对象不存在,则创建一个服务对象.

所以只有一个实例,并且在调用之后它没有被清理.这就像您的WCF服务的Singleton.因此,您需要注意共享内存和资源.

回答你的问题 - 是的,这是它的工作方式.

更新 添加样本:我从MSDN修改了一些样本以显示效果InstanceContextMode.Single.即使我使用两个不同的客户端,您也会看到操作计数将继续增加.如果我更改InstanceContextModePerCall,则计数将不同(它将为零).

自托管服务:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class CalculatorService : ICalculatorInstance
{
    static Object syncObject = new object();
    static int instanceCount;
    int instanceId;
    int operationCount;

    public CalculatorService()
    {
        lock (syncObject)
        {
            instanceCount++;
            instanceId = instanceCount;
        }
    }

    public double Add(double n1, double n2)
    {
        operationCount++;
        return n1 + n2;
    }

    public double Subtract(double n1, double n2)
    {
        Interlocked.Increment(ref operationCount);
        return n1 - n2;
    }

    public double Multiply(double n1, double n2)
    {
        Interlocked.Increment(ref operationCount);
        return n1 * n2;
    }

    public double Divide(double n1, double n2)
    {
        Interlocked.Increment(ref operationCount);
        return n1 / n2;
    }

    public string GetInstanceContextMode()
    {   // Return the InstanceContextMode of the service
        ServiceHost host = (ServiceHost)OperationContext.Current.Host;
        ServiceBehaviorAttribute behavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
        return behavior.InstanceContextMode.ToString();
    }

    public int GetInstanceId()
    {   // Return the id for this instance
        return instanceId;
    }

    public int GetOperationCount()
    {   // Return the number of ICalculator operations performed 
        // on this instance
        lock (syncObject)
        {
            return operationCount;
        }
    }
}

public class Program
{

    static void Main(string[] args)
    {
        Uri baseAddress = new Uri("http://localhost:12345/calc");
        using (ServiceHost host = new ServiceHost(typeof(CalculatorService), baseAddress))
        {
            // Enable metadata publishing.
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            // Open the ServiceHost to start listening for messages. Since
            // no endpoints are explicitly configured, the runtime will create
            // one endpoint per base address for each service contract implemented
            // by the service.
            host.Open();

            Console.WriteLine("The service is ready at {0}", baseAddress);
            Console.WriteLine("Press <Enter> to stop the service.");
            Console.ReadLine();

            // Close the ServiceHost.
            host.Close();
        }
        Console.WriteLine();
        Console.WriteLine("Press <ENTER> to terminate client.");
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

客户:

class Program
{
    static void Main()
    {
        // Create a client.
        CalculatorInstanceClient client = new CalculatorInstanceClient();
        string instanceMode = client.GetInstanceContextMode();
        Console.WriteLine("InstanceContextMode: {0}", instanceMode);
        Console.WriteLine("client1's turn");
        Console.WriteLine("2 + 2 = {0}", client.Add(2, 2).ToString());
        Console.WriteLine("3 - 1 = {0}", client.Subtract(3, 1).ToString());
        Console.WriteLine("number of operations = {0}", client.GetOperationCount().ToString());

        // Create a second client.
        CalculatorInstanceClient client2 = new CalculatorInstanceClient();

        Console.WriteLine("client2's turn");
        Console.WriteLine("2 + 2 = {0}", client2.Add(2, 2).ToString());
        Console.WriteLine("3 - 1 = {0}", client2.Subtract(3, 1).ToString());
        Console.WriteLine("number of operations = {0}", client2.GetOperationCount().ToString());

        Console.WriteLine();
        Console.WriteLine("Press <ENTER> to terminate client.");
        Console.ReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)