C# WCF服务实例的生存期?

C# WCF服务实例的生存期?,c#,wcf,C#,Wcf,在创建WCF服务的过程中,我遇到了一个新术语。基本上,在指定InstanceContextMode时,我有几个选项,包括PerSession、PerCall和Single。下面是我学习的示例代码: [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class EvalService : IEvalService { ... 现在,他这样说,在运行时只会创建我的服务的一个实例。这是什么意思?我认为每次

在创建WCF服务的过程中,我遇到了一个新术语。基本上,在指定
InstanceContextMode
时,我有几个选项,包括
PerSession
PerCall
Single
。下面是我学习的示例代码:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class EvalService : IEvalService { ...
现在,他这样说,在运行时只会创建我的服务的一个实例。这是什么意思?我认为每次连接到web服务时,它都被视为一个单独的实例

对于每个请求,我的服务实例是否持续存在?从中提到的其他成员判断,是否可以安全地假设这就是它的工作方式?

根据文档:

只有一个InstanceContext对象用于所有传入呼叫,并且 通话后未回收。如果服务对象没有 存在,一个被创造

所以只有一个实例,并且在调用后它不会被清理。这就像您的WCF服务的单例。因此,您需要小心共享内存和资源

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

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

自助服务:

[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();
    }
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
公共类计算器服务:iCalculator实例
{
静态对象syncObject=新对象();
静态int实例计数;
int instanceId;
整数运算计数;
公共计算器服务()
{
锁定(同步对象)
{
instanceCount++;
instanceId=instanceCount;
}
}
公共双加(双n1,双n2)
{
运算计数++;
返回n1+n2;
}
公共双减法(双n1,双n2)
{
联锁。增量(参考操作计数);
返回n1-n2;
}
公共双乘(双n1,双n2)
{
联锁。增量(参考操作计数);
返回n1*n2;
}
公共双除法(双n1,双n2)
{
联锁。增量(参考操作计数);
返回n1/n2;
}
公共字符串GetInstanceContextMode()
{//返回服务的InstanceContextMode
ServiceHost主机=(ServiceHost)OperationContext.Current.host;
ServiceBehaviorAttribute behavior=host.Description.Behaviors.Find();
返回行为.InstanceContextMode.ToString();
}
public int GetInstanceId()
{//返回此实例的id
返回instanceId;
}
public int GetOperationCount()
{//返回执行的ICalculator操作数
//在这种情况下
锁定(同步对象)
{
返回操作计数;
}
}
}
公共课程
{
静态void Main(字符串[]参数)
{
Uri baseAddress=新Uri(“http://localhost:12345/calc");
使用(ServiceHost主机=新的ServiceHost(typeof(CalculatorService),baseAddress))
{
//启用元数据发布。
ServiceMetadataBehavior smb=新ServiceMetadataBehavior();
smb.HttpGetEnabled=true;
smb.MetadataExporter.PolicyVersion=PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
//打开ServiceHost以开始侦听消息。自
//没有显式配置端点,运行时将创建
//实现的每个服务契约的每个基址一个端点
//通过服务。
host.Open();
WriteLine(“服务在{0}处准备就绪”,基地址);
控制台。WriteLine(“按以停止服务”);
Console.ReadLine();
//关闭ServiceHost。
host.Close();
}
Console.WriteLine();
Console.WriteLine(“按以终止客户端”);
Console.ReadLine();
}
}
客户:

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();
    }
}
类程序
{
静态void Main()
{
//创建一个客户端。
CalculatorInstanceClient=新建CalculatorInstanceClient();
字符串instanceMode=client.GetInstanceContextMode();
WriteLine(“InstanceContextMode:{0}”,instanceMode);
Console.WriteLine(“轮到客户1”);
WriteLine(“2+2={0}”,client.Add(2,2.ToString());
WriteLine(“3-1={0}”,client.Subtract(3,1.ToString());
WriteLine(“操作数={0}”,client.GetOperationCount().ToString());
//创建第二个客户端。
CalculatorInstanceClient客户端2=新的CalculatorInstanceClient();
Console.WriteLine(“轮到客户2”);
WriteLine(“2+2={0}”,client2.Add(2,2.ToString());
WriteLine(“3-1={0}”,client2.Subtract(3,1.ToString());
WriteLine(“操作数={0}”,client2.GetOperationCount().ToString());
Console.WriteLine();
Console.WriteLine(“按以终止客户端”);
Console.ReadLine();
}
}

这意味着WCF只创建了类的一个实例。所有请求都由该实例处理。包括多线程和并发问题


虽然这可能是一个实现细节,但我怀疑您的类是persistet(它必须是可序列化的,这不是一个要求)。只要需要,一个实例就存在(即关联的
ServiceHost
是打开的)。

是的,共享服务实例意味着服务器只创建了一个实例,在