注意:之後此係列博文若是無特別說明,解決方案都按以前的Client、Host、Service方式進行創建,客戶端代理類採用工具Scvutil.exe生成,若是不清楚能夠參考此係列以前的博文。html
using System.ServiceModel; using System.Threading; namespace Service { [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)] public class SampleMethod:ISampleMethod { public string MethodOne(string msg) { OperationContext operationContext = OperationContext.Current; InstanceContext instanceContext = operationContext.InstanceContext; string info = "InstanceContext HashCode: " + instanceContext.GetHashCode().ToString(); System.Threading.Thread.Sleep(2000); return "You called MethodOne return message is: " + msg + "\n->" + info + "\n->ManagedThreadId:" +
Thread.CurrentThread.ManagedThreadId.ToString()+" "+System.DateTime.Now.ToString(); } public string MethodTwo(string msg) { OperationContext operationContext = OperationContext.Current; InstanceContext instanceContext = operationContext.InstanceContext; string info = "InstanceContext HashCode: " + instanceContext.GetHashCode().ToString(); System.Threading.Thread.Sleep(3000); return "You called MethodTwo return message is: " + msg + "\n->" + info + "\n->ManagedThreadId:" +
Thread.CurrentThread.ManagedThreadId.ToString() + " " + System.DateTime.Now.ToString(); } } }
客戶端採用異步方式進行處理,因此Svcutil.exe必須生成異步客戶端(svcutil.exe /out:f:\SampleMethodClient.cs /config:f:\App.confighttp://localhost:1234/SampleMethod /a /tcv:Version35),客戶端參考代碼以下: 安全
using System; namespace Client { class Program { static void Main(string[] args) { SampleMethodClient client1 = new SampleMethodClient(); client1.MethodOneCompleted += new EventHandler<MethodOneCompletedEventArgs>(client1_MethodOneCompleted); client1.MethodOneAsync("Client1 called MethodOne"); client1.MethodTwoCompleted += new EventHandler<MethodTwoCompletedEventArgs>(client1_MethodTwoCompleted); client1.MethodTwoAsync("Client1 called MethodTwo"); SampleMethodClient client2 = new SampleMethodClient(); client2.MethodOneCompleted += new EventHandler<MethodOneCompletedEventArgs>(client2_MethodOneCompleted); client2.MethodOneAsync("Client2 called MethodOne"); client2.MethodTwoCompleted += new EventHandler<MethodTwoCompletedEventArgs>(client2_MethodTwoCompleted); client2.MethodTwoAsync("Client2 called MethodTwo"); Console.Read(); } static void client2_MethodOneCompleted(object sender, MethodOneCompletedEventArgs e) { Console.WriteLine(e.Result.ToString()); } static void client2_MethodTwoCompleted(object sender, MethodTwoCompletedEventArgs e) { Console.WriteLine(e.Result.ToString()); } static void client1_MethodOneCompleted(object sender, MethodOneCompletedEventArgs e) { Console.WriteLine(e.Result.ToString()); } static void client1_MethodTwoCompleted(object sender, MethodTwoCompletedEventArgs e) { Console.WriteLine(e.Result.ToString()); } } }
運行結果:服務器
結果說明:多線程
Client1處理MethodOne和MethodTwo的時間點不一樣,可是處理的實例上下文ID和線程ID是一致的,這驗證了上面的組合處理模型,而且因爲客戶端產生了兩個代理,併發
創建了兩個會話,因此Client1和Client2的實例上下文ID不一致。異步
運行結果:工具
結果說明:spa
Client1處理MethodOne和MethodTwo的時間點不一樣,雖然處理的實例上下文ID一致,但線程ID是不一致的,這驗證了上面的組合處理模型,而且因爲客戶端產生了兩個代理,線程
創建了兩個會話,因此Client1和Client2的實例上下文ID不一致。3d