首先陈述下个人理解:由于单调模式每次都生成新的实例上下文,所以对于单调模式来说,并发模式是选择single还是multiple没有什么区别。
但是我试验了下,发现对于单调模式下的single和multiple还是有区别。这个要怎么理解呢?
我在客户端并发调用了5次服务端的方法,第一次服务端使用multiple模式,测试结果显示服务端是并行执行的指令,由于单例模式每次都生成新的实例上下文,所以每次都是一个新的实例上下文执行方法这个倒是好理解;后来使用single模式,测试结果显示服务端是串行指令的。按照理解,不应该也是并行执行指令的吗?
贴个代码:客户端:
public void ConnectServer()
{
try
{
NetTcpBinding aNetTcpBinding = new NetTcpBinding();
// set aNetTcpBinding
Uri uri = new Uri("net.tcp://192.168.78.100:12345/TestServer");
EndpointAddress aEndpointAddress = new EndpointAddress(uri);
DuplexChannelFactory<ITest> fac = new DuplexChannelFactory<ITest>(new InstanceContext(this), aNetTcpBinding, aEndpointAddress);
TestServer = fac.CreateChannel();
////所以,当你真的需要执行基于相同服务代理的并发调用的时候,请务必对服务代理进行显式开启
(TestServer as ICommunicationObject).Open();
ThreadPool.QueueUserWorkItem(delegate(object ooo)
{
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem((b) =>
{
LoginEntity aLoginEntity = new LoginEntity();
aLoginEntity.ClientId = "123";
if (TestServer.Login(aLoginEntity))
{
Console.WriteLine(DateTime.Now + ":client login success...");
//ThreadPool.QueueUserWorkItem((a) => testHeart());
}
});
}
});
}
catch (Exception ex)
{
}
}
你需要同时设置 InstanceContextMode 和 ConcurrencyMode 。
http://msdn.microsoft.com/zh-cn/library/vstudio/system.servicemodel.instancecontextmode.aspx
http://msdn.microsoft.com/zh-cn/library/vstudio/system.servicemodel.concurrencymode.aspx
InstanceContextMode是设置为单调模式per-call的,ConcurrencyMode并发模式是single和multiple的这两种
两种我都设置了的,但是在试验percall模式过程中,结合concurrency并发设置,有点疑问。就是按照我的理解percall每一次调用都是新的instancecontext,而concurrency是针对每一个instancecontext来说的,所以,我理解为percall处理服务代理请求都是并发进行的。应该和concurrentcy的设置没有什么关系才对,但是实验的结果并不是这样的。当concurrency设置为single的时候是串行的,multiple的时候才是并行的。这个不知道要如何i理解http://www.cnblogs.com/artech/archive/2010/03/30/1700865.html我是看的这篇
@噹里个噹: 你贴的文章很好,但是你没有仔细读那篇文章,作者总结的很详细,其测试客户端也考虑了多进程和多线程,单通道和双通道,会话和非会话的区别。你这里用了 tcp binding,还使用了 DuplexChannel,所以请你结合你的例子中的这些特点,再去认真的读一下作者的文章。
我看了下文章里的这段话:
并发的问题挺多,到这里还没完。现在我们保留上面修改过的代码(确保在进行并发服务调用之前显示开启服务代理),将客户端和服务终结点采用的绑定类型从WS2007HttpBinding换成NetTcpBinding或者NetNamedPipeBinding。在此运行我们的监控程序,你又将得到类似于如图2所示的监控信息。也就是说,如果采用向NetTcpBinding或者NetNamedPipeBinding这种天生就支持会话的绑定类型(因为它们基于的传输协议提供了对会话的原生支持,HTTP协议本身是没有会话的概念的),对于基于单个服务代理的同步调用,最终表现出来仍就是串行化执行。这是WCF信道架构体系设计使然,我个人对这个设计不以为然。
但是不清楚为什么最终会表现出串行的效果,是客户端调用的时候被串行了还是服务处理请求的时候
@噹里个噹: 你建立一个 tcp 通道后,就打开了一个 tcp 会话,此时只有一条物理连接,那么在这条连接上发送、接收数据都是串行的,这在客户端和服务端都是一样的。你可以试着编写一个 socket server(或看别人的 socket server 源码),你就应该能理解。如果你采用 http 的话,那么每次请求,客户端可以建立一条新的 tcp 连接(或复用已有的连接),从而在客户端和服务器之间形成多个通信管道,也就能实现并行了。
@Launcher: 你说的这个倒是事实。但是我现在不明白的是,对于percall模式,concurrency这个配置项起的什么作用。
目前,我觉得吧concurrency理解为针对同一个服务代理的服务实例并发模式,这样能解释我试验的结果
5个不同的客户端,发起5个耗时的操作,
1、percall+single:互相之间没有各等待5s
2、percall+multiple:互相之间没有各等待5s
同一个客户端发起5次耗时操作请求
1、percall+gingle:串行进行,操作之间间隔了5s
2、percall+multiple:互相之间没有各等待5s
@噹里个噹: InstanceContextMode 控制服务实例的生存周期,ConcurrencyMode 控制服务的多线程行为。
单调模式是什么模式?
WCF有三种调用模式(官方名字记不起来了):
@小AI: 嗯,的确有这样的模式,英文叫Per-Call,以前没接触过
有个concurrency设置来着,记不起来了,WCF的概念太多了,建议看看那个WCF programming什么的那本老外的书,写的很清楚,我忘记了。
你在服务器建一个Service,里面建一个Index属性,然后在ContractMethod里面++,然后返回index,然后用不同的模式进行多次调用,然后检测index的值。
@小AI: 三种服务端激活模式倒是大概知道他们的造成的结果。但是在试验percall模式过程中,结合concurrency并发设置,有点疑问。就是按照我的理解percall每一次调用都是新的instancecontext,而concurrency是针对每一个instancecontext来说的,所以,我理解为percall处理服务代理请求都是并发进行的。应该和concurrentcy的设置没有什么关系才对,但是实验的结果并不是这样的。当concurrency设置为single的时候是串行的,multiple的时候才是并行的。这个不知道要如何i理解