91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

WCF簡單教程(6) 單向與雙向通訊

發布時間:2020-06-14 11:01:19 來源:網絡 閱讀:5703 作者:BoyTNT 欄目:編程語言

第六篇:單向與雙向通訊

項目開發中我們時常會遇到需要異步調用的問題,有時忽略服務端的返回值,有時希望服務端在需要的時候回調,今天就來看看在WCF中如何實現。

先看不需要服務端返回值的單向調用,老規矩,直接上代碼,再解釋。

1、服務端

契約接口中增加一個Sleep方法:

  1. using System;  
  2. using System.ServiceModel;  
  3. using System.Text;  
  4.   
  5. namespace Server  
  6. {  
  7.     [ServiceContract(Namespace="WCF.Demo")]  
  8.     public interface IData  
  9.     {  
  10.         [OperationContract]  
  11.         string SayHello(string userName);  
  12.  
  13.         /// <summary> 
  14.         /// IsOneWay = true 表明這是一個單向調用,注意返回值是void,因為既然是單向調用,客戶端肯定不會等待接收返回值的 
  15.         /// </summary> 
  16.         [OperationContract(IsOneWay = true)] 
  17.         void Sleep(); 
  18.     }  


對應的實現類中,我們來實現這個方法:

  1. using System;  
  2. using System.Text;  
  3.   
  4. namespace Server  
  5. {  
  6.     public class DataProvider : IData  
  7.     {  
  8.         public string SayHello(string userName)  
  9.         {  
  10.             return string.Format("Hello {0}.", userName);  
  11.         }  
  12.  
  13.         /// <summary> 
  14.         /// 實現Sleep方法,暫時不做任何事情,只是睡眠5秒 
  15.         /// </summary> 
  16.         public void Sleep() 
  17.         { 
  18.             Thread.Sleep(5000); 
  19.         } 
  20.     }  
  21. }  

App.config就不再列出來了,里面用的是一個netTcpBinding的endpoint。


2、客戶端

首先別忘了客戶端的契約要與服務端保持一致,App.config也不列出來了,里面有對應的endpoint。主要是調用的代碼:

  1. using System;  
  2. using System.ServiceModel;  
  3. using System.ServiceModel.Channels;  
  4.   
  5. namespace Client  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             var proxy = new ChannelFactory<Server.IData>("DataService").CreateChannel();  
  12.  
  13.             //先調用SayHello方法  
  14.             Console.WriteLine(proxy.SayHello("WCF"));  
  15.             //調用一下Sleep方法,按我們的設想,它應該是異步的,所以不會阻塞后面的調用 
  16.             proxy.Sleep(); 
  17.             //再調用一次SayHello方法  
  18.             Console.WriteLine(proxy.SayHello("WCF"));  
  19.             //關閉連接  
  20.             ((IChannel)proxy).Close();  
  21.     }  

按我們的設想,兩次SayHello調用之間應該沒有延遲,因為Sleep是異步的嘛,編譯運行一下,結果……  中間卡住了5秒,這是為什么呢?

這其中涉及到一個并發模型的問題,默認情況下,WCF以單線程模型對外提供服務,也就是說,只能一個一個處理請求,即使是一個OneWay的單向調用,也只能等它處理完后才會接著處理后面的SayHello請求,所以會卡5秒。

并發模式有以下三種,MSDN上的介紹有點復雜,我給簡化一下:

Single:單線程調用,請求只能一個一個處理;

Reentrant:可重入的單線程調用,本質仍是單線程,處理回調時,回調請求會進入隊列尾部排隊;

Multiple:多線程調用,請求是并發的響應的;


調置服務并發模型是在契約的實現類上,我們為DataService類加一個Attribute:

  1. /// <summary> 
  2. /// 用ServiceBehavior為契約實現類標定行為屬性,此處指定并發模型為ConcurrencyMode.Multiple,即并發訪問 
  3. /// </summary> 
  4. [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
  5. public class DataProvider : IData 
  6.     //略 


這回再編譯運行一下,連續打出了2行 Hello WCF,中間不再阻塞了。

 

現在我們再來看看雙向通訊的問題。雙向通訊可以基于HTTP、TCP、Named Pipe、MSMQ,但要注意,basicHttpBinding和wsHttpBinding不行,要換用wsDualHttpBinding,它會創建兩個連接來進行雙向通訊。至于TCP,它天然就是雙向通訊的。

1、服務端

服務契約要進行修改,增加關于回調的契約:

  1. using System; 
  2. using System.ServiceModel; 
  3. using System.ServiceModel.Description; 
  4.  
  5. namespace Server 
  6.     /// <summary> 
  7.     /// 增加了CallbackContract的標識,用于指明針對此服務契約的回調契約是IDataCallback 
  8.     /// </summary> 
  9.     [ServiceContract(Namespace = "WCF.Demo", CallbackContract = typeof(IDataCallback))] 
  10.     public interface IData 
  11.     { 
  12.         [OperationContract] 
  13.         string SayHello(string userName); 
  14.  
  15.         [OperationContract(IsOneWay = true)] 
  16.         void Sleep(); 
  17.     } 
  18.  
  19.     /// <summary> 
  20.     /// 定義服務回調契約,注意它沒有契約標識,只是個一般接口 
  21.     /// </summary> 
  22.     public interface IDataCallback 
  23.     { 
  24.         /// <summary> 
  25.         /// 定義一個回調方法,由于回調不可能要求對方再響應,所以也標識成OneWay的調用,同樣不需要有返回值 
  26.         /// </summary> 
  27.        [OperationContract(IsOneWay = true)] 
  28.        void SleepCallback(string text); 
  29.     } 


對應的契約實現類要修改一下:

  1. using System; 
  2. using System.ServiceModel; 
  3. using System.ServiceModel.Description; 
  4. using System.Threading; 
  5. using System.Net; 
  6.  
  7. namespace Server 
  8.     [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
  9.     public class DataProvider : IData 
  10.     { 
  11.         public string SayHello(string userName) 
  12.         { 
  13.             string.Format("Hello {0}.", userName); 
  14.         } 
  15.  
  16.         public void Sleep() 
  17.         { 
  18. //先睡5秒
  19.             Thread.Sleep(5000); 
  20.  
  21. //用OperationContext.Current來獲取指定類型的回調對象 
  22.             var callback = OperationContext.Current.GetCallbackChannel<IDataCallback>(); 
  23. //回調SleepCallback方法,并傳遞參數 
  24.             callback.SleepCallback("睡醒了"); 
  25.         } 
  26.     } 


2、客戶端

仍然提醒一下別忘了把新的服務契約更新到客戶端。客戶端的調用要調整一下:

  1. using System;  
  2. using System.ServiceModel;  
  3. using System.ServiceModel.Channels;  
  4.   
  5. namespace Client  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             //定義一個實現回調接口的類實例 
  12.             var context = new DataCallbackImp(); 
  13.             //創建代理的時候變了,要用DuplexChannelFactory,因為IData契約已經標識了有回調,所以必須要用支持雙向通訊的ChannelFactory,傳入剛才創建的回調實例 
  14.             var proxy = new DuplexChannelFactory<Server.IData>(context, "DataService").CreateChannel();  
  15.  
  16.             //調用Sleep 
  17.             proxy.Sleep(); 
  18.             //調用SayHello方法  
  19.             Console.WriteLine(proxy.SayHello("WCF"));  
  20.  
  21.             //等待按任意鍵,先不要關連接 
  22.             Console.ReadKey(); 
  23.             ((IChannel)proxy).Close();  
  24.     }  
  25.  
  26.     /// <summary> 
  27.     /// 實現回調接口中的類,圖省事寫到這里了 
  28.     /// </summary> 
  29.     class DataCallbackImp : Server.IDataCallback 
  30.     { 
  31.         /// <summary> 
  32.         /// 實現SleepCallback方法 
  33.         /// </summary> 
  34.         public void SleepCallback(string text) 
  35.         { 
  36.             Console.WriteLine("收到回調了:" + text); 
  37.         } 
  38.     } 


編譯運行,屏幕先顯示一行“Hello WCF.”,過5秒后顯示“收到回調了:睡醒了”。

 

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

荆州市| 东乡族自治县| 乌拉特中旗| 岗巴县| 聂拉木县| 宜丰县| 卓资县| 静宁县| 怀化市| 宽城| 界首市| 仁寿县| 灵寿县| 清流县| 黄龙县| 读书| 如东县| 龙川县| 合阳县| 塘沽区| 方正县| 锦州市| 梧州市| 正阳县| 新建县| 崇明县| 虎林市| 黄石市| 漳浦县| 阜南县| 阿尔山市| 海兴县| 马关县| 宾阳县| 自治县| 申扎县| 山东省| 通化县| 蒙自县| 汾西县| 鹿邑县|