一、前言
上一篇我们简单介绍了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
相关
搜索
复制