<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      重入與回調并發(Reentrant & CallbackConcurrency )

      WCF中,并發是一個很影響服務性能的重要方面。通過ServiceBehaviorAttribute中的ConcurrencyMode可以設置服務的并發性。

      對于雙工通訊來說,服務對客戶端的回調也是通過代理完成的。那么這又涉及到另外一個問題:回調客戶端時,能否讓回調服務也并發執行呢?WCF中定義了CallbackBehaviorAttribute ,可以通過它來設置回調服務的行為。它同樣定義了ConcurrencyMode,可指定回調的并發模式,但它沒有定義回調的實例模式,即InstanceContextMode。本文主要探討服務的并發與回調服務的并發。

      目錄:

       

      1. 測試重入與回調并發 
      2. 會話對 重入與回調并發 
      3. 設置服務并發的ServiceBehaviorAttribute能用于回調服務嗎?
      通過實例進行說明:

       

      契約定義:
      [ServiceContract(CallbackContract = typeof(IAddCallback))]   

      publicinterface IAdd
      {
          [OperationContract]
          void Add(int x, int y);
      }

      回調契約定義:
          public interface IAddCallback  

          {
              [OperationContract]
              void ShowResult(int result);
          }

      服務實現:
          public class AddService : IAdd 

          {
              private readonly int counter;

              public AddService()
              {
                  counter++;
                  Console.ResetColor();
                  Console.WriteLine(string.Format("AddService Construction function excute... counter is {0}", counter));
              }

              #region IAdd 成員

              public void Add(int x, int y)
              {
                  var clientId = OperationContext.Current.IncomingMessageHeaders.GetHeader<int>(MessageWrapper.headerClientId,
                                                                                                MessageWrapper.headerNamespace);
                  Console.ForegroundColor = ConsoleColor.Red;
                  Console.WriteLine(string.Format("Time:{0};ThreadId is :{1}.Request Id is {2} Add Method Invoked,", DateTime.Now,
                                                  Thread.CurrentThread.ManagedThreadId, clientId));
                  Thread.Sleep(5000);
                  int result = x + y;
                  MessageHeader<int> header = new MessageHeader<int>(clientId);
                  System.ServiceModel.Channels.MessageHeader messageHeader =
                      header.GetUntypedHeader(MessageWrapper.headerClientId,
                                              MessageWrapper.headerNamespace);
                  OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);
                  Console.WriteLine(string.Format("Time: {1} Requst Id {0} begin Callback",clientId,DateTime.Now));
                  IAddCallback callbackProxy= OperationContext.Current.GetCallbackChannel<IAddCallback>();
                  callbackProxy.ShowResult(result);
                  Console.WriteLine(string.Format("Time: {1} Requst Id {0} Callback finished", clientId, DateTime.Now));
                  Console.WriteLine(string.Format("result is : {0}",result));
                  Thread.Sleep(5000);
                  Console.WriteLine("=========Excute finished=========");
                  Console.WriteLine();
              }

              #endregion
          }

      服務配置:
          
          <system.serviceModel>

      <services>
                  <service name="Service.AddService">
                      <endpoint address="http://127.0.0.1:3636/AddService" binding="wsDualHttpBinding" contract="Contract.IAdd" ></endpoint>
                  </service>
              </services>
          </system.serviceModel>

      客戶端調用:
          public class AddCallback : IAddCallback
          {
              private readonly int counter;
              public AddCallback()
              {
                  counter++;
                  Console.WriteLine(string.Format("AddCallback Construction function excute... counter is {0}", counter));
              }

              #region IAddCallback 成員

              public void ShowResult(int result)
              {            
                  int callbackRequestId= OperationContext.Current.IncomingMessageHeaders.GetHeader<int>(MessageWrapper.headerClientId,
                                                                                 MessageWrapper.headerNamespace);
                  Console.ForegroundColor = ConsoleColor.Yellow;
                  Console.WriteLine(string.Format("Time: {1} ThreadId is :{2} Callback RequestId : {0} 開始執行回調", callbackRequestId, DateTime.Now,Thread.CurrentThread.ManagedThreadId));
                  Thread.Sleep(10000);
                  Console.WriteLine(string.Format("Add result is {0}", result));
                  Console.WriteLine(string.Format("Time: {1} ThreadId is :{2} Callback RequestId : {0} 回調結束", callbackRequestId, DateTime.Now, Thread.CurrentThread.ManagedThreadId));
                  Console.WriteLine("==================");
                  Console.WriteLine();
              }
      #endregion 
            }  

      回調服務實現:
      static void InvokeWithDiffrentProxy()
              {
                  InstanceContext instanceContext=new InstanceContext(new AddCallback());
                  DuplexChannelFactory<IAdd> factory = new DuplexChannelFactory<IAdd>(instanceContext,"AddService");
                  for (int i = 0; i < 2; i++)
                  {
                      IAdd proxy = factory.CreateChannel();
                      ThreadPool.QueueUserWorkItem(delegate
                                                       {
                                                           int clientId = Interlocked.Increment(ref index);
                                                           using (
                                                               OperationContextScope contextScope =
                                                                   new OperationContextScope(proxy as IContextChannel))
                                                           {
                                                               MessageHeader<int> header = new MessageHeader<int>(clientId);
                                                               System.ServiceModel.Channels.MessageHeader messageHeader =
                                                                   header.GetUntypedHeader(MessageWrapper.headerClientId,
                                                                                           MessageWrapper.headerNamespace);
                                                               OperationContext.Current.OutgoingMessageHeaders.Add(messageHeader);
                                                               proxy.Add(12);
                                                           }
                                                       });
                  }
              }
      注意:如果XP下,使用wsDualHttpBinding作為綁定協議,需要對綁定做一下設置:
      <bindings>
          <wsDualHttpBinding>
              <bind name="wsDuplexBinding">
                  <clientBaseAddress  address="http://127.0.0.1:6300/addCallbackService">
              <bind>
              <wsDualHttpBinding>
      </bindings>
      下面做幾個測試,觀察一下服務端以及回調客戶端的執行。

       

      測試1:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.Single

      客戶端:ConcurrencyMode = ConcurrencyMode.Single
      回調服務休眠10秒
      服務端輸出:
       
      客戶端輸出:
       
       

      測試2:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.Single

      客戶端:ConcurrencyMode = ConcurrencyMode.Single
      回調服務休眠1秒
      服務端輸出:

       

      客戶端輸出:

       

      通過測試1、2的一組圖的輸出可知:Reentrant + Single 模式下:服務一次只能執行一個服務,當服務執行回調時,請求隊列中的下一個請求將被服務執行。在回調服務的單實例模式下:回調也需要排隊等待被處理。測試2的一組圖顯示:調用1的回調在時間為11:25:10的時候回調已經完成,但是回到服務端時,另外一個服務正占用鎖,它只能等待。這說明:當回調服務完成,回調客戶端時,需要等待服務正在被處理的請求釋放鎖后才能被繼續執行。
      測試3:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ConcurrencyMode = ConcurrencyMode.Single
      服務端輸出:

       

      客戶端輸出:

       

      通過上圖分析知:服務對調用的請求通過并發的方式執行,而服務對客戶端的回調還是串行的方式。
      測試4:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerCall

       客戶端:ConcurrencyMode = ConcurrencyMode.Single

      服務端輸出:

       

      客戶端輸出:
       
      測試結果和測試3一樣。
      測試5:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.Single

      客戶端:ConcurrencyMode = ConcurrencyMode.Multiple
      服務端輸出:

       

      客戶端輸出:

       

      通過上圖分析知:服務對調用的請求通過串行的方式執行,而服務對客戶端的回調是并行的方式。
      測試6:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ConcurrencyMode = ConcurrencyMode.Multiple
      服務端輸出:

       

      客戶端輸出: 

       

      通過上圖分析知:服務對調用的請求以及服務對客戶端的回調是并行的方式。
      測試7:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ConcurrencyMode = ConcurrencyMode.Multiple
      服務端輸出:

       

      客戶端輸出: 

       

      通過上圖分析知:服務對調用的請求以及服務對客戶端的回調是并行的方式。
      測試8會話模式

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ConcurrencyMode = ConcurrencyMode.Single
      服務端輸出:

       

      客戶端輸出:

       

      通過上圖分析知:服務對調用的請求并發進行處理,服務對客戶端的回調以串行的方式處理。
      測試9會話模式:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ConcurrencyMode = ConcurrencyMode.Multiple
      服務端輸出:

       

      客戶端輸出:

       

      服務對調用的請求以及服務對客戶端的回調是并行的方式。
      如果將ServiceBehaviorAttribute用于回調類型,結果會怎樣呢?
      測試10會話模式

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)
      服務端輸出:

       

      客戶端輸出:

       

      通過上圖分析知:服務對調用的請求并發進行處理,服務對客戶端的回調以并行的方式處理。
      測試11會話模式:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,InstanceContextMode = InstanceContextMode.PerCall)
      服務端輸出:


      客戶端輸出:

       

      測試12會話模式:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,InstanceContextMode = InstanceContextMode.PerSession)
      服務端輸出:

       

      客戶端輸出:

       

      測試10、測試11、測試12分析知:服務對調用的請求并發進行處理;服務對客戶端的回調以串行的方式處理,這點可以從回調的構造,以及打印出來的時間兩方面得到驗證。
      對回調使用ServiceBehaviorAttribute無效。
      測試13會話模式:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      客戶端:ConcurrencyMode = ConcurrencyMode.Single
      同一客戶端并發調用服務,將調用代碼做如下更改:
      (proxy as ICommunicationObject).Open();
      服務端輸出:

       

      客戶端輸出:
      測試14會話模式:

      ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      ConcurrencyMode = ConcurrencyMode.Multiple
      同一客戶端并發調用服務,將調用代碼做如下更改:
      (proxy as ICommunicationObject).Open();
      服務端輸出:

       

      客戶端輸出:
      測試15:

      ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerSession

      ConcurrencyMode = ConcurrencyMode.Multiple
      同一客戶端并發調用服務,將調用代碼做如下更改:
      (proxy as ICommunicationObject).Open();
      服務端輸出:

       

      客戶端輸出: 

       

      測試16:

      ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerCall

      ConcurrencyMode = ConcurrencyMode.Multiple
      同一客戶端并發調用服務,將調用代碼做如下更改:
      (proxy as ICommunicationObject).Open();
      服務端輸出:

       

      客戶端輸出:

      測試17:

      ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.Single

      ConcurrencyMode = ConcurrencyMode.Multiple
      同一客戶端并發調用服務,將調用代碼做如下更改:
      (proxy as ICommunicationObject).Open();

      服務端輸出:

       

      客戶端輸出:

       

       

      測試18:

      服務端:ConcurrencyMode = ConcurrencyMode.Reentrant,InstanceContextMode = InstanceContextMode.PerCall

      客戶端:ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,InstanceContextMode = InstanceContextMode.PerCall) 

      服務端輸出:

       

      客戶端輸出:

       

       

        由測試10、11、12、18這些測試得出如下結論:ServiceBehaviorAttribute對回調服務的并發設置無效。

       會話模式下,不同客戶端代理對可重入的服務總是以并發的方式執行;相同客戶端對可重入的服務總是以串行的方式執行,而無論怎樣,回調服務總是以串行的方式執行。

       

      posted @ 2012-05-24 23:46  tyb1222  閱讀(6139)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 久热这里只精品视频99| 妇女性内射冈站hdwww000| 无码专区视频精品老司机| 国产手机在线αⅴ片无码观看| 亚洲av成人一区二区三区| 国产在线视频一区二区三区| 视频一区二区三区四区久久| 国产一区二区日韩在线| 亚洲国产中文在线有精品| 亚洲精品一区二区区别| 中文字幕日韩有码国产| 久久综合色一综合色88欧美| 国产性三级高清在线观看| 国产极品粉嫩尤物一区二区| XXXXXHD亚洲日本HD| 无码人妻斩一区二区三区| 亚洲在av极品无码天堂| 无码人妻人妻经典| 午夜羞羞影院男女爽爽爽| 日本偷拍自影像视频久久| 国产成人不卡无码免费视频| 富川| 九九视频热最新在线视频| 最新国产精品好看的精品| 驻马店市| 国产在线午夜不卡精品影院| 色九九视频| 日韩人妻一区中文字幕| 四虎成人在线观看免费| 日本一道一区二区视频| 61精品人妻一区二区三区| 天堂a无码a无线孕交| 蜜臀精品视频一区二区三区| 理论片午午伦夜理片影院99| 日本一区二区三区小视频| 40岁成熟女人牲交片20分钟| 粉嫩av国产一区二区三区| 中文字幕永久精品国产| 婷婷六月综合缴情在线| 自拍偷自拍亚洲精品播放| 国产乱人伦av在线无码|