因為MSMQ的使用需要不斷的查看隊列是否有新消息,所以一般是結合Windows的服務,當然也可以用一個不關閉的Winform程序,不過前者更好一些,不怕被人誤關。
完成MSMQ的WindowsService項目后,將服務項目添加到Windows 服務中。
①如果訪問的是一個已經存在的隊列,那么啟動的時候會報錯誤【本地計算機上的XXXX服務啟動后停止。某些服務在未由其他服務或程序使用時將自動停止】
這是因為沒有分配權限。
處理方法:右擊要訪問的隊列 ->安全
將Everyone和ANONYMOUS LOGON的完全控制分別勾選

②發送消息到遠程隊列
訪問本地隊列時,隊列的路徑格式及使用是這樣子的
var mqPath = @".\Private$\MyMQ"; MessageQueue _MQ; if (MessageQueue.Exists(mqPath)) { _MQ = new MessageQueue(mqPath); } else { _MQ = MessageQueue.Create(mqPath); }
訪問遠程隊列時,代碼略有不同:
1.遠程隊列的路徑格式:string path = @"Formatname:DIRECT=tcp:192.168.1.11\Private$\myMQ"; 關鍵字不區分大小寫
2.MSMQ 判斷隊列是否存在的方法(MessageQueue.Exists(string path))和創建隊列(MessageQueue.Create(string path)),都是不支持遠程隊列的。
1.使用Exists方法會出現錯誤【無法確定具有指定格式名的隊列是否存在。】
2.使用Create方法會出現錯誤【無法創建路徑為 FormatName:DIRECT=tcp:192.168.1.11\Private$\myMQ 的隊列】
3.由於前兩條的限制,如果要訪問遠程專用隊列,則必須保證事先在遠程機器上該隊列是存在的。
var path = @"FormatName:DIRECT=tcp:192.168.1.11\Private$\myMQ"; MessageQueue mq = new MessageQueue(queuePath);
4.當發送消息到遠程隊列時,系統會在本機的傳出隊列下創建一個臨時隊列,每發送一條消息,該消息都會先存在臨時隊列中,這樣做的目的是防止因遠程隊列無法訪問而丟失消息。
不過要特別注意的是,如果遠程機器不能成功連接,則消息就一直在臨時隊列中存放;如果能成功連接,即使要訪問的隊列並不存在,消息發送程序也不會報錯,並且臨時隊列中的消息會刪除。
所以 一定要保證先在遠程服務器上建好隊列。傳出隊列具體信息如下圖:


5.如果事務型屬性不匹配,消息將無法傳遞。系統不會返回任何錯誤,但該條消息卻會丟掉。
