WCF服务实例的生存期? [英] The lifetime of an instance of a WCF service?
问题描述
在创建WCF服务的过程中,我遇到了一个新术语.基本上,当指定 InstanceContextMode
时,我有一些选择,包括: PerSession
, PerCall
和 Single
.这是我正在学习的示例中的代码:
in the process of creating a WCF service I ran into a term that's new to me. Basically when specifying the InstanceContextMode
I have a few options, including; PerSession
, PerCall
and Single
. Here's the code from the sample I'm learning from:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
public class EvalService : IEvalService { ...
现在,他这样做是说在运行时将仅创建我的服务的一个实例.这是什么意思?我以为每次与Web服务建立连接时,都会将其视为单独的实例.
Now, he stated by doing this that only one instance of my service would be created at runtime. What does this mean? I thought that everytime a connection was made to the web service that it was treated as a seperate instance.
对于我的每个请求,此服务实例是否都持续存在?由 docs 中提到的其他成员判断,是可以安全地假设这是它的工作方式吗?
Does it persist, this instance of my service, for every request made? Judging by the other members mentioned in the docs, is it safe to assume this is the way it works?
推荐答案
每个文档:
只有一个InstanceContext对象可用于所有传入呼叫,并且是通话后未回收.如果服务对象没有存在,一个被创建.
Only one InstanceContext object is used for all incoming calls and is not recycled subsequent to the calls. If a service object does not exist, one is created.
因此,只有一个实例,并且在调用后不会清除它.这就像您的WCF服务的Singleton.因此,您需要注意共享内存和资源.
So there is only one instance, and it's not cleaned up after a call is made. This is like a Singleton for your WCF service. So you need to be careful about shared memory and resources.
要回答您的问题-是的,这就是它的工作方式.
To answer your question - yes, this is the way it works.
更新添加了示例:我从MSDN修改了一些示例,以显示 InstanceContextMode.Single
的效果.即使我使用两个不同的客户端,您也会看到操作计数将继续增加.如果我将 InstanceContextMode
更改为 PerCall
,则计数将有所不同(为零).
UPDATE Added sample:
I modified a few samples from MSDN to show the effects of InstanceContextMode.Single
. You'll see the operation count will continue to increment even though I use two different clients. If I change the InstanceContextMode
to PerCall
, the count will be different (it will be zero).
自托管服务:
[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();
}
}
客户端:
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();
}
}
这篇关于WCF服务实例的生存期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!