自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

P2PMessageQueue的實(shí)際用法

開發(fā) 后端
本文介紹如何使用P2PMessageQueue(點(diǎn)對(duì)點(diǎn)消息隊(duì)列)。您將看到使用 P2PMessageQueue 類和相關(guān)類型的示例。

使用 P2PMessageQueue

本部分,您將看到使用 P2PMessageQueue 類和相關(guān)類型的示例。

注 當(dāng)運(yùn)行該示例時(shí),可以選擇部署到 Windows CE 或 Pocket PC 2003 模擬器或設(shè)備。您可以在不進(jìn)行修改的情況下在任一個(gè)平臺(tái)上調(diào)試該項(xiàng)目(并運(yùn)行該應(yīng)用程序)。運(yùn)行示例時(shí),看到的第一個(gè)屏幕提示您在閱讀器進(jìn)程和發(fā)送器進(jìn)程間進(jìn)行選擇。無論選擇哪一個(gè),都必須再次運(yùn)行 .exe 文件(從 Program Files),然后選擇另一個(gè)選項(xiàng)。在 Pocket PC 平臺(tái)上,無論是使用模擬器還是設(shè)備,都必須重命名 .exe 文件(否則將激活現(xiàn)有的運(yùn)行中應(yīng)用程序)。

字符串的簡單 IPC 交換

首先使用托管進(jìn)程將字符串傳入另一個(gè) .NET Compact Framework 應(yīng)用程序(也可以使發(fā)送方或接收方成為本機(jī)應(yīng)用程序。有三種不同的方法用來讀取接收端的字符串(相同的原理也適用于發(fā)送端):阻塞、非阻塞以及事件驅(qū)動(dòng)。

發(fā)送方和接收方的圖形用戶界面 (GUI) 在功能方面是自描述性的,如圖 3、4 和 5 所示。

 主窗體

圖 3. 主窗體

讀取端 

圖 4. 讀取端

當(dāng)發(fā)送方單擊 Send 按鈕時(shí),發(fā)送一個(gè)字符串(如文本框中輸入的),并可以選擇將該消息設(shè)置為警告消息(基于 Message Is Alert 復(fù)選框狀態(tài))。發(fā)送方會(huì)阻塞,直到針對(duì)指定超時(shí)發(fā)送該消息(作為 combobox 中選擇的發(fā)送方)。位于該復(fù)選框下面的窗體底部顯示 Send 方法的返回結(jié)果,如圖 5 所示(即 OK)。

 發(fā)送 / 編寫端

圖 5. 發(fā)送 / 編寫端

這里再次使用了下載示例中的 Send 方法。

  1. private void cmdSend_Click(object sender, System.EventArgs e) {  
  2. Message msg;  
  3.  
  4. msg = new Message(  
  5. System.Text.Encoding.ASCII.GetBytes(txtSend.Text),   
  6. chkIsAlert.Checked);  
  7.  
  8.     ReadWriteResult rwr = mQue.Send(msg, mTimeout);  
  9.     lblSendResult.Text = rwr.ToString();  
  10. }  
  11.  

當(dāng)閱讀器收到一個(gè)消息后,會(huì)將它顯示在列表視圖(第三列)中,并指出它是否是警告消息(第二列)。當(dāng)成功接收到該消息時(shí),第一列將始終顯示 OK。默認(rèn)情況下,要接收一個(gè)消息,請單擊 Receive 按鈕;如果沒有消息要接收或者方法失敗,則列表視圖的第一列將指出原因(另兩列在該情形中不適用)。

在讀取和發(fā)送時(shí),Queue Info 菜單(單擊 Info,然后單擊 Queue Info)會(huì)顯示有關(guān)隊(duì)列的數(shù)據(jù)。接收端上的 Mode 菜單(單擊 Read,然后單擊 Mode)有三個(gè)菜單項(xiàng):On Demand Only、Event driven 和 Block a Thread。這些項(xiàng)用于配置該程序如何接收隊(duì)列外的消息。當(dāng)您選擇一個(gè)模式后,它在示例應(yīng)用程序的生命周期內(nèi)不應(yīng)該更改(開發(fā)人員可針對(duì)自己的設(shè)計(jì)進(jìn)行混合與匹配)。以下幾個(gè)小節(jié)描述三種讀取模式。

按命令讀(對(duì)應(yīng)于菜單 On Demand Only )

當(dāng)接收方單擊 Receive 按鈕時(shí),將執(zhí)行以下方法。

  1. private void cmdReceive_Click(object sender, System.EventArgs e) {  
  2.     Message msg;  
  3.     msg = new Message();  
  4.  
  5.     // mTimeout is set by the end user by means of the GUI   
  6.     // to DON'T BLOCK (0), BLOCK (-1), or a real timeout value  
  7.     ReadWriteResult rwr = mQue.Receive(ref msg, mTimeout);  
  8.  
  9.     ListViewItem lvi;  
  10. if (rwr == ReadWriteResult.OK){   
  11.     bool isAlrt;  
  12.         string payload;  
  13.         isAlrt = msg.IsAlert;  
  14.  
  15.         byte[] bytes = msg.MessageBytes;  
  16.         payload = System.Text.Encoding.ASCII.GetString(  
  17.                 bytes, 0, bytes.GetLength(0));  
  18.  
  19.         lvi = new ListViewItem(  
  20.                 new string[]{rwr.ToString(), isAlrt.ToString(), payload});  
  21. }else{        
  22.         lvi = new ListViewItem(  
  23.                 new string[]{rwr.ToString(), @"n\a", @"n\a"});  
  24.     }  
  25.         listView1.Items.Add(lvi);  
  26.         listView1.Columns[2].Width = -2;}  
  27.  

事件驅(qū)動(dòng)

事件驅(qū)動(dòng)模型基本上意味著應(yīng)用程序不會(huì)在任意時(shí)刻通過調(diào)用 Receive(例如,在計(jì)時(shí)器上或者要求用戶單擊 Receive 按鈕)來輪詢新消息,相反,應(yīng)用程序會(huì)訂閱并捕獲來自 P2PMessageQueue 類的事件。要訂閱事件,需要使用正規(guī)的 .NET Compact Framework 委托習(xí)語(隊(duì)列的創(chuàng)建也不例外)。

  1. mQue = new P2PMessageQueue(  
  2.     isReader, txtQueueName.Text, maxL, maxM, out firstTime);  
  3. mQue.DataOnQueueChanged += new EventHandler(mQue_DataOnQueueChanged);  

引發(fā)該事件會(huì)調(diào)用方法,在本例中,只調(diào)用現(xiàn)有的接收方法。

  1. private void mQue_DataOnQueueChanged(object sender, EventArgs e) {  
  2.     this.Invoke(new EventHandler(this.cmdReceive_Click));  
  3. }  

阻塞線程

第三種從隊(duì)列進(jìn)行讀取的方法是:創(chuàng)建一個(gè)線程,并使其阻塞以等待隊(duì)列的 Receive 方法。每次接收到消息時(shí),應(yīng)用程序都會(huì)處理它,然后再次循環(huán)回阻塞。以下是一些帶有解釋的示例代碼。

您會(huì)在某個(gè)地方創(chuàng)建并啟動(dòng)以下線程。

  1. Thread t = new Thread(new ThreadStart(ThreadBlockedOnRead));  
  2. t.Start();  

該線程用下面的方法運(yùn)行。(有關(guān)更多上下文,請下載代碼)。

  1. private void ThreadBlockedOnRead(){  
  2.     while (mMode == 2){ // Thread mode  
  3.         Message msg = new Message();  
  4.  
  5.         //Can actually omit a timeout for a true infinite block   
  6.         ReadWriteResult rwr = mQue.Receive(msg, 60 * 1000);  
  7.         if (rwr == ReadWriteResult.InvalidHandle || mMode != 2){  
  8.             return;  
  9.         }  
  10.                   
  11.         string body = rwr.ToString();  
  12.         if (rwr == ReadWriteResult.OK){  
  13.             byte[] bytes = msg.MessageBytes;  
  14.             string bytesAsString =   
  15. System.Text.Encoding.ASCII.GetString(  
  16. bytes, 0, bytes.GetLength(0));  
  17.             body += " | " + msg.IsAlert.ToString() + " | " + bytesAsString;  
  18.         }  
  19.  
  20.         MessageBox.Show(body, "To terminate this mode use the menu again");  
  21.     }  
  22. }      
  23.  

基本示例代碼至此結(jié)束。讀取隊(duì)列的三種方式也可以應(yīng)用于通過隊(duì)列發(fā)送。當(dāng)事件接收到信號(hào)時(shí)(即,隊(duì)列從已滿轉(zhuǎn)變?yōu)槲礉M),可進(jìn)行阻塞和發(fā)送或嘗試在不進(jìn)行阻塞的情況下隨時(shí)進(jìn)行發(fā)送。在下一部分中,您將看到該設(shè)計(jì)如何允許隊(duì)列中的消息包含其他結(jié)構(gòu) — 而不僅僅是字符串。

注 在開發(fā)一個(gè)依賴事件信號(hào)來識(shí)別隊(duì)列從已滿轉(zhuǎn)變?yōu)槲礉M的應(yīng)用程序時(shí),需要在應(yīng)用程序啟動(dòng)時(shí)針對(duì)隊(duì)列執(zhí)行一個(gè)初始寫入操作。如果不執(zhí)行該初始寫入操作,則應(yīng)用程序永遠(yuǎn)不會(huì)開始寫入,因?yàn)樵摮跏紝懭氩僮鞅仨毥?jīng)過特定地執(zhí)行才能填充轉(zhuǎn)變?yōu)槲礉M狀態(tài)的隊(duì)列,因此,向事件發(fā)出信號(hào)以觸發(fā)針對(duì)該隊(duì)列的進(jìn)一步寫入操作。

發(fā)送和接收更復(fù)雜的類型(不僅僅是字符串)

在前幾部分中,是在應(yīng)用程序之間傳遞字符串,但如果可以將字符串與字節(jié)數(shù)組進(jìn)行轉(zhuǎn)換,則還可以傳遞任何數(shù)據(jù)類型。因此,將該類型轉(zhuǎn)換為一個(gè)字節(jié)數(shù)組,在其中創(chuàng)建 Message 類,然后發(fā)送 Message。在接收端,檢索 Message,獲取字節(jié)數(shù)組,然后在其中創(chuàng)建該類型(例如,公開類型的 ToBytes 和 FromBytes 方法)。另一個(gè)方法是,從 Message 類繼承自己的類,并在其中實(shí)現(xiàn)轉(zhuǎn)換。很自然,如果您嘗試傳遞一個(gè)復(fù)雜的對(duì)象圖,則在類型與字節(jié)數(shù)組之間進(jìn)行轉(zhuǎn)換會(huì)難得多。嘗試使用沒有源代碼的類型需要特別注意,因?yàn)槟赡懿痪哂袑?duì)該類型的完整狀態(tài)(例如,私有成員)的訪問權(quán),因此,可能無法準(zhǔn)確地在類型與字節(jié)數(shù)組之間進(jìn)行轉(zhuǎn)換。

出于簡單的目的,假設(shè)將一個(gè) Int64 和一個(gè) Boolean 從一個(gè)進(jìn)程傳遞到另一個(gè)進(jìn)程。將創(chuàng)建一個(gè) CustomMessage 類,如下所示。

  1. public class CustomMessage : Message {  
  2.     public long TotalMemory;  
  3.     public bool AfterGC;  
  4.     public CustomMessage(){  
  5.         TotalMemory = 0;  
  6.         AfterGC = false;  
  7.     }  
  8.     public CustomMessage(long totMem, bool afterGarbCol){  
  9.         TotalMemory = totMem;  
  10.         AfterGC = afterGarbCol;  
  11.     }  
  12.     public override byte[] MessageBytes {  
  13.         get {  
  14.             byte[] b1 = BitConverter.GetBytes(TotalMemory);  
  15.             byte[] b2 = BitConverter.GetBytes(AfterGC);  
  16.  
  17.             byte[] b = new byte[9];  
  18.             Buffer.BlockCopy(b1, 0, b, 0, 8);  
  19.             Buffer.BlockCopy(b2, 0, b, 8, 1);  
  20.             return b;  
  21.         }  
  22.         set {  
  23.             TotalMemory = BitConverter.ToInt64(value, 0);  
  24.             AfterGC = BitConverter.ToBoolean(value, 8);  
  25.             base.MessageBytes = value;  
  26.         }  
  27.     }  
  28. }  

添加了兩個(gè)感興趣的字段(TotalMemory、AfterGC),重寫 MessageBytes 屬性以實(shí)現(xiàn)轉(zhuǎn)換(get 和 set 方法位于轉(zhuǎn)換發(fā)生的位置),然后添加一個(gè)默認(rèn)的構(gòu)造函數(shù)(這個(gè)參數(shù)化的構(gòu)造函數(shù)是可選的)。

現(xiàn)在,如果要使用前面的示例,只需更改兩處地方:

發(fā)送消息時(shí),要?jiǎng)?chuàng)建一個(gè) CustomMessage,而不是將值賦給 TotalMemory 和 AfterGC。

  1. //msg = new Message(. . .); //Instead of this line  
  2. msg = new CustomMessage(GC.GetTotalMemory(false), false);  
  3. ReadWriteResult rwr = mQue.Send(msg, mTimeout);  

接收消息時(shí),要?jiǎng)?chuàng)建一個(gè) CustomMessage。

  1. //msg = new Message();  
  2. msg = new CustomMessage(); //msg still declared as Message  
  3. ReadWriteResult rwr = mQue.Receive(msg, mTimeout);  

然后,在 mQue.Receive 返回時(shí)讀取它的屬性。

  1. //byte[] bytes = msg.MessageBytes;  
  2. //payload = System.Text.Encoding.ASCII.GetString(. . .);  
  3. payload = "Total Memory = " + ((CustomMessage)msg).TotalMemory.ToString() +   
  4.                     (((CustomMessage)msg).AfterGC ? " after a GC" : " without forcing a GC");  
  5.  

【編輯推薦】

  1. 點(diǎn)對(duì)點(diǎn)消息隊(duì)列函數(shù):用于WinCE的IPC機(jī)制
  2. ASP.NET中無Cookie會(huì)話的優(yōu)點(diǎn)與缺點(diǎn)
  3. 無Cookie會(huì)話的實(shí)現(xiàn)
  4. ASP.NET Cookie:不是問題的問題
  5. .NET框架中的XML:XmlSerializer的內(nèi)部原理
責(zé)任編輯:yangsai 來源: MSDN
相關(guān)推薦

2009-08-06 16:27:05

P2PMessageQ

2010-05-31 14:16:01

MySQL數(shù)學(xué)函數(shù)

2010-04-28 14:46:38

Oracle Copy

2010-04-28 14:56:02

Oracle sqlp

2010-04-28 16:30:52

Oracle case

2010-05-04 12:10:08

Oracle over

2010-05-07 18:52:59

Oracle rown

2010-05-17 17:23:27

MySQL limit

2010-05-05 15:38:31

Oracle安全策略

2010-04-29 13:31:16

Oracle Orad

2010-04-27 14:44:31

Oracle存儲(chǔ)過程

2010-05-26 16:53:21

MySQL show

2010-04-06 08:58:27

Oracle job

2010-04-29 10:41:55

2012-01-06 10:59:37

Nuget

2010-04-29 13:53:42

Oracle臨時(shí)表

2010-06-30 13:07:17

SQL Server函

2012-12-10 09:46:21

P2P云存儲(chǔ)Symform

2010-07-07 10:31:45

2010-05-13 16:32:18

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)