wcf并发行为是用于管理被关联到同一服务实例上的不同消息的处理,也可以理解为同一个客户端代理发送的多个请求,同一个服务实例怎么处理。
WCF中有三种并发行为可以设置。
single=0 默认设置
Reentrant=1
Multiple=2
1. Single模式
Single是默认的并发模式是默认的并发设置,WCF服务实例会为客户端的每一个请求提供同步锁,服务实例一次只能处理一个请求,多余的请求需要排队等待,类似于串行执行,不能并行。如果在排队等待的过程中,有一个请求等待超时,客户端将抛出异常。
下面的代码用多线程演示了客户端的同一个代理发送多个请求,服务器只能按顺序排队处理。上一个请求执行完成后,才能处理下一个请求的信息。
服务器端契约
[ServiceContract] public interface ISingle { [OperationContract] void SendMsg(string msg); } [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Single)] public class SingleImpl:ISingle,IDisposable { public void Dispose() { Console.WriteLine("释放实例"); } public void SendMsg(string msg) { Console.WriteLine("开始"+msg); System.Threading.Thread.Sleep(3000); Console.WriteLine("完成"+msg); Console.WriteLine("----------------------------"); } }
客户端代码,客户端采用异步方式调用,调用WCF服务的时候,我们选择生成异步操作
private void button1_Click(object sender, EventArgs e) { SingleService.SingleClient client = new SingleService.SingleClient(); for (int i = 0; i < 5; i++) { client.BeginSendMsg(i.ToString(), new AsyncCallback(CallBackSendMsg), null); } } void CallBackSendMsg(IAsyncResult ar) { Console.WriteLine("返回结果"); }
执行结果
2. MultiPle模式
Multiple模式允许一个客户端代理进行多线程访问,实现了并发访问,提高了系统处理效率,只需要对关键性资源加锁就可以了。把锁放在了系统的最小范围内。
下面的代码使用multiple模式展示了客户端代理使用多线程进行异步访问操作。
服务器端契约
[ServiceContract] public interface IMultiple { [OperationContract] void SendMsg(string msg); } [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] public class MultipleImpl:IMultiple,IDisposable { public void Dispose() { Console.WriteLine("释放实例"); } public void SendMsg(string msg) { Console.WriteLine("开始" + msg); System.Threading.Thread.Sleep(3000); Console.WriteLine("结束" + msg); } }
客户端
void CallBackSendMsg(IAsyncResult ar) { Console.WriteLine("返回结果"); } private void button2_Click(object sender, EventArgs e) { MultiService.MultipleClient client = new MultiService.MultipleClient(); for (int i = 0; i < 5; i++) { client.BeginSendMsg(i.ToString(), new AsyncCallback(CallBackSendMsg), null); } }
3.Reentrant模式
Reentrant模式和single模式一样,也是单线程访问操作,但是是有区别的,当同一个客户端向服务器发送请求时候,服务器端客户回调客户端的操作,不会造成死锁,这样在一些耗时的服务操作中,能够提高服务实例的处理速度和吞吐量。这个主要是为双工模式服务的。
服务器契约
[ServiceContract(CallbackContract=typeof(ICallBack))] public interface IReentrant { [OperationContract] void SendMsg(string msg); } public interface ICallBack { [OperationContract] string GetResult(string msg); } [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)] public class ReentrantImpl:IReentrant,IDisposable { public void SendMsg(string msg) { Console.WriteLine("开始"+msg); System.Threading.Thread.Sleep(3000); ICallBack callback = OperationContext.Current.GetCallbackChannel<ICallBack>(); callback.GetResult(msg); Console.WriteLine("结束"+msg); } public void Dispose() { Console.WriteLine("释放实例"); } }
客户端
private void button3_Click(object sender, EventArgs e) { InstanceContext instanceContext = new InstanceContext(new CallBackService()); ServiceReen.ReentrantClient client = new ServiceReen.ReentrantClient(instanceContext); for (int i = 0; i < 5; i++) { //client.BeginSendMsg(i.ToString(), new AsyncCallback(CallBackSendMsg), null); client.SendMsg(i.ToString()); } } } public class CallBackService : ServiceReen.IReentrantCallback { #region IReentrantCallback 成员 public string EndGetResult(IAsyncResult result) { throw new NotImplementedException(); } #endregion #region IReentrantCallback 成员 public string GetResult(string msg) { Console.WriteLine("返回结果"+msg); return msg; } public IAsyncResult BeginGetResult(string msg, AsyncCallback callback, object asyncState) { throw new NotImplementedException(); } #endregion }
执行结果
demo :http://download.csdn.net/detail/zx13525079024/4606269