初次使用消息队列

因为项目的需要,做了个OPC Client端,用其实现从OPC Server上实时取数,并将取出来的数提供给WebService,由于需要很快的刷新频率,不能把取出的数据写入到关系数据库,于是想到用一种内存共享的机制,找来找去,觉得用消息队列就可以满足要求了(也没有找到其他在C#下实现内存共享的方式,汗啊)。

废话不表,要用消息队列,首先要求机器上要安装消息队列......

另一要注意的问题,非域内机器,只能用私有队列,这就意味着WebService要和OPC Client端在同一台机器上

代理片段:

using System.Messaging;

 

protected string mqPath = @".private$MQSendOPCValueTableForDisplay";//私有消息队列名称

 

        void mySubscription_DataChanged(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
        
{
            DataTable myTagInfo 
= new DataTable();
            myTagInfo.TableName 
= "OPCValueInfo";
            myTagInfo.Columns.Add(
"TagName"typeof(string));
            myTagInfo.Columns.Add(
"TagValue"typeof(string));
            myTagInfo.Columns.Add(
"TagQuality"typeof(string));
            
if (InvokeRequired)
            
{
                
//保证过程运行,其它控件响应事件也不能影响。
                BeginInvoke(new DataChangedEventHandler(mySubscription_DataChanged), new object[] { subscriptionHandle, requestHandle, values });//系统调用。
                return;
            }

            
try
            
{
                DataRow myRow;
                
foreach (ItemValueResult item in values)
                
{
                    myRow 
= myTagInfo.NewRow();
                    myRow[
"TagName"= item.ItemName.ToString();
                    myRow[
"TagValue"= item.Value.ToString();
                    myRow[
"TagQuality"= item.Quality.ToString();
                    myTagInfo.Rows.Add(myRow);
                }

            }

            
catch
            
{

            }


            
if (!MessageQueue.Exists(mqPath))
            
{
                MessageQueue.Create(mqPath);
            }

            MessageQueue mq 
= new MessageQueue(mqPath);
            mq.Purge();
//发送之前清空消息队列,保持消息队列中始终是最新的
            mq.Send(myTagInfo);
        }

好了,消息队列发送完毕。

下面是接收:

 

 protected string mqPath = @".private$MQSendOPCValueTableForDisplay";
.
.
.    [WebMethod]
    
public String[] GetTagValueInfo()
    
{
        DataTable TagInfo 
= new DataTable();
        TagInfo.TableName 
= "TagInfo";
        MessageQueue mq 
= new MessageQueue(mqPath);
        mq.Formatter 
= new XmlMessageFormatter(new Type[] typeof(DataTable) });
        
string[] result = null;

        
try
        
{
            TimeSpan mySpan 
= new TimeSpan(0020);
            System.Messaging.Message m 
= mq.Receive(mySpan);
            TagInfo 
= (DataTable)m.Body;
            result 
= new string[TagInfo.Rows.Count];
            
for (int i = 0; i < TagInfo.Rows.Count; i++)
            
{
                result[i] 
= TagInfo.Rows[i][1].ToString();
            }

        }

        
catch
        
{

        }

        
return result;
    }
 
### C#消息队列使用场景 #### 应用解耦 在C#环境中,消息队列用于解耦应用程序的不同部分。这种设计模式允许各个模块独立发展而不互相影响。例如,在订单处理系统中,前端接收客户提交的新订单请求并将其发送到消息队列;后台服务则负责监听该队列中的新条目,并执行相应的业务逻辑来完成订单创建过程[^1]。 #### 异步通信 为了提升用户体验以及优化资源利用率,许多操作可以通过异步方式进行处理。比如当用户上传文件至服务器时,可以直接返回成功状态给客户端而无需等待整个文件被完全保存完毕。此时就可以利用消息队列为后续的任务排队,如压缩图片、转换视频格式等耗时较长的工作可以在后台逐步完成[^2]。 #### 流量控制与负载均衡 面对突发性的大量访问请求,直接由单一的服务实例承担可能会导致性能瓶颈甚至崩溃的风险。借助于消息队列能够有效地缓解这一情况——它可以作为缓冲区存储暂时无法立即处理的信息直到有足够的计算能力去消化它们。此外,多个消费者可以从同一个队列读取消息从而分担工作负荷,实现了简单的水平扩展方案[^3]。 #### 日志记录与监控报警 对于大型分布式系统而言,集中式的日志管理和实时告警是非常必要的功能之一。通过配置专门的日志收集器订阅特定主题下的事件通知(即消息),并将这些数据转发给第三方平台做进一步分析或触发预警机制。这种方式不仅简化了部署流程而且提高了运维效率。 #### 数据同步 跨数据库之间的增量更新往往涉及到复杂的事务管理难题。如果采用传统方法可能造成严重的锁竞争现象进而降低整体吞吐率。相比之下,基于消息驱动的方式更加灵活高效:每当源端发生变更后立即将变动详情推送到目标端的消息通道里供其消费解析即可达成一致的状态迁移效果。 ```csharp using System; using System.Messaging; class Program { static void Main() { string queuePath = @".\private$\exampleQueue"; // 创建私有消息队列 (仅需首次运行) if (!MessageQueue.Exists(queuePath)) { MessageQueue.Create(queuePath); } using(MessageQueue mq = new MessageQueue(queuePath)){ // 发送一条测试消息 mq.Send("This is a test message."); Console.WriteLine("Message sent to the queue."); // 接收并显示接收到的第一条消息 var receivedMsg = mq.Receive(); Console.WriteLine($"Received message: {receivedMsg.Body}"); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值