一、前言
上一篇我們簡單介紹了MicroSoft Message Queuing
(微軟消息隊列)的安裝、連接MSMQ要用到的類庫以及API。所以在本篇將在.NET程序中演練MSMQ。
二、演練開始
首先給大家展示演練項目的整體設計,比如我是使用WinForm+控制檯
的形式演練,功能包括消息發送(Send)、隊列創建、消息獲取(Peek、Receive)、隊列刪除(Delete)等。
1.總覽
演練項目使用的是WinForm+控制檯
的形式,左邊紅色區域中是我們要實現MSMQ管理的功能,右邊是我們需要創建的項目。
Queue:隊列
Plant:生產的消息數量
Send:向隊列發送消息,當隊列不存在時提示是否創建隊列。
Peek:使用Peek方式獲取隊列
Receive:使用Receive方式獲取隊列
Delete:刪除隊列
下面是動態效果圖,加載可能會慢一些。
2.創建MSMQDemo
此程序的功能主要包括隊列創建、刪除、消息發送。消息獲取將分別調用Peek、Receive程序。代碼都有相應的註釋,也比較容易理解。
下面上代碼,項目代碼可以帶Github上下載,文章底部也有下載鏈接
using MSMQDemo.Model;
using System;
using System.Diagnostics;
using System.Messaging;
using System.Windows.Forms;
namespace MSMQDemo
{
/// <summary>
/// @ desc:MSMQ演示用例,包括隊列的連接、驗證、創建、刪除、消息發送、接受。
/// @ author:yz
/// @ date:2017-10-10
/// </summary>
public partial class main : Form
{
// 操作類型 1:Peek 2:Receive
public int type = 0;
// 隊列地址
public string queueputh = string.Empty;
// 隊列名稱
public string queuename = string.Empty;
/// <summary>
/// @ desc:主函數
/// </summary>
public main()
{
InitializeComponent();
}
/// <summary>
/// @ desc:發送
/// @ author:yz
/// </summary>
private void Send_Click(object sender, EventArgs e)
{
string queuename = Queue.Text;
int count = trackBar.Value;
try
{
if (string.IsNullOrEmpty(queuename))
{
MessageBox.Show("請輸入隊列!");
return;
}
if (count == 0)
{
MessageBox.Show("請設置發送數量!");
return;
}
string _QueuePath = string.Format(@".\private$\{0}", queuename);
if (!MessageQueue.Exists(_QueuePath))
{
if (MessageBox.Show(string.Format("隊列\"{0}\"不存在是否創建?", queuename), string.Format("創建隊列"), MessageBoxButtons.YesNo, MessageBoxIcon.None) == DialogResult.Yes)
{
// 創建隊列
MessageQueue.Create(_QueuePath);
if (MessageBox.Show(string.Format("隊列\"{0}\"成功,是否繼續發送數據?", queuename), string.Format("發送數據"), MessageBoxButtons.YesNo, MessageBoxIcon.None) != DialogResult.Yes)
{
return;
}
}
else
{
return;
}
}
// 開始生產數據
for (int i = 0; i < count; i++)
{
MessageQueue localQueue = new MessageQueue(_QueuePath);
System.Messaging.Message msg = new System.Messaging.Message()
{
Body = new KeyModel() { guid = Guid.NewGuid(), time = DateTime.Now },
Formatter = new XmlMessageFormatter(new Type[] { typeof(KeyModel) })
};
localQueue.Send(msg);
}
MessageBox.Show(string.Format("成功發送 {0} 條消息到\"{1}\"隊列!", count, queuename));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// @ desc:使用Receive方式獲取隊列
/// @ author:yz
/// </summary>
private void Receive_Click(object sender, EventArgs e)
{
if (verify(2))
{
Process.Start(Application.StartupPath + @"\Receive.exe", queuename);
}
}
/// <summary>
/// @ desc:使用Peek方式查看隊列
/// @ author:yz
/// </summary>
private void Peek_Click(object sender, EventArgs e)
{
if (verify(1))
{
Process.Start(Application.StartupPath + @"\Peek.exe", queuename);
}
}
/// <summary>
/// @ desc:刪除隊列
/// @ author:yz
/// </summary>
private void Delete_Click(object sender, EventArgs e)
{
if (verify(0))
{
if (MessageBox.Show(string.Format("確認刪除\"{0}\"隊列?", queuename), string.Format("刪除隊列"), MessageBoxButtons.YesNo, MessageBoxIcon.None) == DialogResult.Yes)
{
MessageQueue.Delete(queueputh);
MessageBox.Show("刪除成功!");
}
}
}
/// <summary>
/// @ desc:滑動條選擇發送數量
/// @ author:yz
/// </summary>
private void trackBar_Scroll(object sender, EventArgs e)
{
label3.Text = trackBar.Value.ToString();
}
/// <summary>
/// @ desc:驗證數據
/// @ author:yz
/// </summary>
/// <param name="_type">類型</param>
/// <returns></returns>
private bool verify(int _type)
{
queuename = Queue.Text;
if (string.IsNullOrEmpty(queuename))
{
MessageBox.Show("請輸入隊列!");
return false;
}
type = _type; queueputh = string.Format(@".\private$\{0}", queuename);
if (!MessageQueue.Exists(queueputh))
{
MessageBox.Show(string.Format("隊列\"{0}\"不存在!", queuename));
return false;
}
return true;
}
}
}
3.Peek調用程序
using Peek.Model;
using System;
using System.Messaging;
namespace Peek
{
/// <summary>
/// @ desc:MSMQ演示用例,使用Peek方式接收隊列。
/// @ author:yz
/// @ date:2017-10-10
/// </summary>
class Program
{
// 隊列路徑
private static string _QueuePath = string.Empty;
/// <summary>
/// @ desc:主函數
/// </summary>
static void Main(string[] args)
{
Console.WriteLine("MQPeek!");
string queuename = Environment.GetCommandLineArgs()[1];
Console.WriteLine(string.Format("You are using \"{0}\" Queue", queuename));
_QueuePath = string.Format(@".\private$\{0}", queuename);
ReceiveMessageByPeek<KeyModel>();
Console.ReadKey();
}
/// <summary>
/// @ desc: 驗證隊列 隊列不存在則創建
/// @ author:yz
/// </summary>
private static bool VerifyQueue()
{
try
{
// 判斷隊列是否存在 不存在則創建
if (!MessageQueue.Exists(_QueuePath))
{
Console.WriteLine(string.Format("\"{0}\"隊列不存在", _QueuePath));
return false;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
return true;
}
/// <summary>
/// @ desc: 採用Peek方式查看消息
/// @ author:yz
/// </summary>
public static void ReceiveMessageByPeek<T>(MessageQueueTransaction tran = null)
{
try
{
if (VerifyQueue())
{
// 初始化消息隊列
MessageQueue localQueue = new MessageQueue(_QueuePath);
localQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
Message msg = localQueue.Peek();
Console.WriteLine(MSMQDemo.Tools.Json.GetJson((T)msg.Body));
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
4.Receive調用程序
using Receive.Model;
using System;
using System.Messaging;
using System.Threading;
namespace Receive
{
/// <summary>
/// @ desc:MSMQ演示用例,使用Receive方式接收隊列。
/// @ author:yz
/// @ date:2017-10-10
/// </summary>
class Program
{
// 隊列路徑
private static string _QueuePath = string.Empty;
// 消息隊列
private static MessageQueue localQueue;
/// <summary>
/// @ desc:主函數
/// </summary>
static void Main(string[] args)
{
Console.WriteLine("MQReceive!");
string queuename = Environment.GetCommandLineArgs()[1];
Console.WriteLine(string.Format("You are using \"{0}\" Queue", queuename));
_QueuePath = string.Format(@".\private$\{0}", queuename);
ReceiveMessage<KeyModel>();
Console.ReadKey();
}
/// <summary>
/// @ desc: 驗證隊列 隊列不存在則創建
/// @ author:yz
/// </summary>
private static bool VerifyQueue()
{
try
{
// 判斷隊列是否存在 不存在則創建
if (!MessageQueue.Exists(_QueuePath))
{
Console.WriteLine(string.Format("\"{0}\"隊列不存在", _QueuePath));
return false;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
}
return true;
}
/// <summary>
/// @ desc:接收消息
/// @ author:yz
/// </summary>
private static void ReceiveMessage<T>(MessageQueueTransaction tran = null)
{
try
{
if (VerifyQueue())
{
localQueue = new MessageQueue(_QueuePath);
localQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(MessageReceived<T>);
localQueue.BeginReceive();
Console.ReadLine();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
/// <summary>
/// @ desc:繼續接收消息
/// @ author:yz
/// </summary>
private static void MessageReceived<T>(object source, ReceiveCompletedEventArgs asyncResult)
{
bool isReceivedSucceed = true;
try
{
//連接到隊列
Message m = localQueue.EndReceive(asyncResult.AsyncResult);
m.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
//顯示處理的消息.
//Console.WriteLine(MSMQDemo.Tools.Json.GetJson((T)m.Body));
ThreadPool.QueueUserWorkItem(new WaitCallback(InvokeMDAO<T>), m.Body);
}
catch (MessageQueueException)
{
isReceivedSucceed = false;
}
catch (Exception ex)
{
isReceivedSucceed = false;
Console.WriteLine(ex.Message);
}
finally
{
if (isReceivedSucceed)
{
localQueue.BeginReceive();
}
}
}
/// <summary>
/// @ desc:接收回調
/// @ author:yz
/// </summary>
private static void InvokeMDAO<T>(object state)
{
try
{
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss :") + MSMQDemo.Tools.Json.GetJson((T)state));
}
catch (Exception)
{
throw;
}
}
}
}
Github:MSMQDemo
相關
搜索
複製