Learning WCF:Life Cycle of Service instance
示例代码下载地址:WCFDemo1Day
概述
客户端向WCF服务发出请求后,服务端会实例化一个Service对象(实现了契约接口的对象)用来处理请求,实例化Service对象以及维护其生命周期的方式在WCF中共有三种不同的类型,分别是:
- Per-Call
- Per-Session
- Single
程序中通过设置ServiceBehavior特性来指定,如下:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class CommService : ICommContract
{
}
这是枚举InstanceContextMode的内容:
public enum InstanceContextMode
{
PerSession = 0,
PerCall = 1,
Single = 2,
}
Per-Call
每次调用服务端服务端方法,服务端都会实例化一个对象来处理请求,为观察结果,现编写如下代码:
服务类:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class CommService : ICommContract
{
public CommService()
{
Console.WriteLine("构造函数被执行");
}
public int Add(int a, int b)
{
Console.WriteLine("Add被调用,Thread:" + Thread.CurrentThread.ManagedThreadId + " fromPool:" + Thread.CurrentThread.IsThreadPoolThread);
return a + b;
}
public void Dispose()
{
Console.WriteLine("对象销毁");
Console.WriteLine("_____________________________");
}
public void SendStr(string str)
{
Console.WriteLine("SendStr被调用,Thread:" + Thread.CurrentThread.ManagedThreadId + " fromPool:" + Thread.CurrentThread.IsThreadPoolThread);
}
}
如果服务类实现了接口IDisposable
,当服务类被销毁时会回调Dispose
方法,可以在Dispose
方法中写一些WriteLine语句以观察对象的生命周期。
客户端代码:
class Program
{
static void Main(string[] args)
{
CommService.CommContractClient client = new CommService.CommContractClient();
client.SendStr("hello");
client.SendStr("hello");
client.SendStr("hello");
client.Close();
}
}
运行效果:
Per-Session
InstanceContextMode
被设置为PerSession
后,同一个客户端多次调用一个远程Web服务方法时,服务端只会实例化一次,修改上面的服务端代码第一行如下:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
再看运行效果:
上面的实例代码所使用的绑定模式为WSHttpBinding
,如果使用BasicHttpBinding
的话,即使是指定了InstanceContextMode
为PerSession
服务端也不会保存会话,现将支持Per-Session
的绑定方式列举如下:
WSXXXBinding(with Message security or reliability)
NetTcpXXXBinding
NetXXXPipeBinding
后两个容易理解,第一个括号里什么什么玩意儿,请看宿主代码:
class Program
{
static void Main(string[] args)
{
Uri baseURI = new Uri("http://localhost:8000/Services");
ServiceHost host = new ServiceHost(typeof(CommService), baseURI);
try
{
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.None;
host.AddServiceEndpoint(typeof(ICommContract), binding, "CommonService");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetUrl = new Uri("http://localhost:8080/Services");
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
host.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
host.Abort();
}
}
}
binding.Security.Mode
默认为Message
,现在把它改成None
再运行程序:
哈,虽然InstanceContextMode
设置为了Per-Session
,实际上还是Per-Call
,这部分内容和安全性有关,希望我有时间以后会写到吧,今天暂时不去研究。
除了绑定方式,还有一个地方也影响到了Per-Session
是否起作用,它是契约接口特性ServiceContract
的属性SessionMode
,该枚举内容如下:
public enum SessionMode
{
Allowed = 0,
Required = 1,
NotAllowed = 2,
}
SessionMode
属性默认是Allowed
,如果设置为Required
表示必须启用会话模式,NotAllowed
表示必须不能启动会话模式,Allowed
表示无所谓。谁有兴趣可以一一尝试。现将契约接口的特性改成如下:
[ServiceContract(Namespace = "zzy0471.cnblogs.com.CommService", SessionMode = SessionMode.NotAllowed)]
public interface ICommContract : IDisposable
{
[OperationContract()]
int Add(int a, int b);
[OperationContract()]
void SendStr(String str);
}
再运行程序:
虽然InstanceContextMode
设置为了Per-Session
,实际上还是Per-Call
。
此外,还有一个需要注意的地方,如果在方法契约特性中设置属性IsTerminating
为true
,如下图
[OperationContract(IsTerminating = true)]
void SendStr(String str);
运行服务端会导致运行时错误,IsTerminating
设置为了true
和Per-Session
模式相矛盾,IsTerminating
的意思是:“获取或设置一个值,该值指示服务操作在发送答复消息(如果存在)后,是否会导致服务器关闭会话”
Per-Single
InstanceContextMode
被设置为PerSingle
后,所有的客户端请求都只有一个服务端实例对象来处理,服务启动时对象创建,服务关闭时对象销毁。现修改InstanceContextMode
特性如下:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class CommService : ICommContract
{
public CommService()
{
Console.WriteLine("构造函数被执行");
}
public int Add(int a, int b)
{
Console.WriteLine("Add被调用,Thread:" + Thread.CurrentThread.ManagedThreadId + " fromPool:" + Thread.CurrentThread.IsThreadPoolThread);
return a + b;
}
public void Dispose()
{
Console.WriteLine("对象销毁");
Console.WriteLine("_____________________________");
}
public void SendStr(string str)
{
Console.WriteLine("SendStr被调用,Thread:" + Thread.CurrentThread.ManagedThreadId + " fromPool:" + Thread.CurrentThread.IsThreadPoolThread);
}
}
为了方便观察,修改客户端代码,以模拟多个客户端:
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 3; i++)
{
CommService.CommContractClient client = new CommService.CommContractClient();
client.SendStr("hello");
client.SendStr("hello");
client.SendStr("hello");
client.Close();
}
}
}
运行程序:
Learning WCF:Life Cycle of Service instance的更多相关文章
- WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇]
原文:WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[下篇] 在[第2篇]中,我们深入剖析了单调(PerCall)模式下WCF对服务实例生命周期的控制,现在我们来 ...
- Learning WCF Chapter1 Creating a New Service from Scratch
You’re about to be introduced to the WCF service. This lab isn’t your typical “Hello World”—it’s “He ...
- Learning WCF:Fault Handling
There are two types of Execptions which can be throwed from the WCF service. They are Application ex ...
- Learning WCF:A Simple Demo
This is a very simple demo which can help you create a wcf applition quickly. Create a Solution Open ...
- Learning WCF Chapter1 Hosting a Service in IIS
How messages reach a service endpoint is a matter of protocols and hosting. IIS can host services ov ...
- Learning WCF Chapter1 Generating a Service and Client Proxy
In the previous lab,you created a service and client from scratch without leveraging the tools avail ...
- Learning WCF Chapter1 Exposing Multiple Service Endpoints
So far in this chapter,I have shown you different ways to create services,how to expose a service en ...
- WCF 的 Service Instance模式和并发处理
WCF 的 Service Instance(实例)有三种模式 PerCall:每一次调用都创建一个实例,每一次调用结束后回收实例.此模式完全无状态. PerSession:调用者打开Channel时 ...
- WCF:为 SharePoint 2010 Business Connectivity Services 构建 WCF Web 服务(第 1 部分,共 4 部分)
转:http://msdn.microsoft.com/zh-cn/library/gg318615.aspx 摘要:通过此系列文章(共四部分)了解如何在 Microsoft SharePoint F ...
随机推荐
- 20165304 2017-2018-2《Java程序设计》学习总结
20165304 2017-2018-2<Java程序设计>学习总结 一.每周作业及实验报告链接汇总 1.我期望的师生关系 2.20165304学习基础和C语言基础调查 3.linux系统 ...
- python_07 函数作用域、匿名函数
函数的作用域:无论在哪个地方调用函数,函数运行过程中的作用域只跟定义的时候有关,跟在哪个地方调用无关. name='alex' def foo(): name = 'linhaifeng' def b ...
- Linux常用基础操作命令大全(超实用精心整理)
相信大家都对黑客那种只用命令行对电脑操作的风格惊呆了,其实你也可以做到.linux是一款不同于windows的操作系统,而且它是黑客.渗透人员.运维人员等等必会的.如果你想学习,小编下面整理的命令将会 ...
- css选择器querySelectorAll
* querySelectorAll(css的选择器)* 通过css的选择器获取到的一组元素* 获取的也是类数组** 主语* document 从整个页面去获取一组元素* 父级 从父级下去获取一组元素 ...
- Nginx – rewrite 配置 URL重写及301跳转原理图
Nginx – rewrite 配置 URL重写 官网:http://nginx.org/en/docs/http/ngx_http_rewrite_module.html 语法:rewrite re ...
- python note 03 切片及对字符串操作
1.计算 1 - 2 + 3 ... + 99 中除了88以外的数之和 i = 1 sum = 0 while i < 100 : if i == 88 : i = i + 1 continue ...
- java通过年月得到该月每一天的日期
public static List<String> getDayByMonth(int yearParam,int monthParam){ List<String> lis ...
- BeanUtils.copyProperties的简单示例
一.新建测试实体 1.UserA package com.dechy.hebswj.test; public class UserA { private String a; private Strin ...
- VMWare 14.1 15 Pro 安装 macOS Mojave 10.14.1系统 遇到的问题解决方案
安装环境 WIN10VMware Workstation Pro 15.0.0 Build 10134415工具准备1.VMware Workstation Pro 15.0.0 Build 1013 ...
- 20172306 2018-2019《Java程序设计与数据结构课堂测试补充报告》
学号 2017-2018-2 <程序设计与数据结构>课堂测试补充报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 刘辰 学号:20172306 实验教师:王志强 必 ...