C#消息队列原理

提到队列,就不得不区分一下栈和队列的本质了。栈:先进后出;队列:先进先出。

使用消息队列的应用比较广的就是分布式开发,加入你有n个客户端,每个客户端都向服务器发送了一条对数据库某字段的操作,但不需要对数据库进行修改,这时候就可以用到消息队列。只要保证消息格式布标,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,达到解耦的目的。话不多说,上简单的queue队列安利。

view  code:指令构造器

/// 维护一个指令队列和一个定时器,串行执行指定设备指令。
/// 添加到指令队列的指令必须实现IDeviceCmd接口。
///
public class DeviceCmdQueue
{
private Queue queue; //指令队列
private Timer timer; //定时执行指令的timer
public readonly int TIMER_INTERVAL; //执行间隔,毫秒

public static ILog logger = LogDispatcher.GetLogger(typeof(DeviceCmdQueue));
        //private System.Net.Sockets.UdpClient UdpSender = null;  //指令公共发送者
///


/// 默认构造器
///

protected DeviceCmdQueue()
{
}
///
/// 构造器,指定指令执行间隔(毫秒数)
///

/// 指令执行间隔,单位毫秒
public DeviceCmdQueue(int interval)
{
            //this.UdpSender = new UdpClient();
this.queue = new Queue();
this.TIMER_INTERVAL = interval;
this.timer = new Timer(new TimerCallback(this.OnTimerCallback), null, interval, interval);
}
///
/// 添加指令到队列。返回指令队列的长度。
///

///
public virtual int Append(IDeviceCmd cmd)
{
            //logger.DebugFormat("{0} cmd in queue", this.queue.Count + 1);
if (cmd == null)
{
return this.queue.Count;
}


lock(this)
{
this.queue.Enqueue(cmd); //指令入队
return this.queue.Count;
}
}
///
/// 获取一条指令。无指令时返回null
///

private bool Fetch(out IDeviceCmd cmd_out)
{
lock(this)
{
long now = DateTime.Now.Ticks;
while(this.queue.Count > 0)
{
//指令出队
IDeviceCmd cmd = (IDeviceCmd)this.queue.Dequeue();


//检查指令是否已经超时
//if (now - cmd.Timestamp < cmd.Timeout * 10000)
{
cmd_out = cmd;
return true;
}
}


cmd_out = null;
return false;
}
}
///
/// 在timer的回调事件中,从指令队列中提取指令并执行
///

private void OnTimerCallback(object state)
{
IDeviceCmd cmd;
if (!this.Fetch(out cmd))
return;


            try
            {
                //if (this.UdpSender == null)
                //{
                //    this.UdpSender = new UdpClient();
                //}
                if (Global.RunningMode == RunningModeEnum.REAL)
                {
                    //实际运行
                    //cmd.Execute(this.UdpSender);//2013-06-18 修改,添加UDP数据公共发送者参数UdpSender
                    cmd.Execute();//2013-06-18 修改,添加UDP数据公共发送者参数UdpSender
                }
                else
                {
                    //模拟运行
                    cmd.Simulate();
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message, ex);

            }
}

}

view  code:指令接口

///


/// 设备指令接口
///

public interface IDeviceCmd
{
///
/// 执行指令
///

        void Execute();


///
/// 模拟执行。
/// 通常情况下,该方法调用DeviceListener.FireOnReceivedFrom方法,
/// 并传入合适的模拟数据
///

void Simulate();


///
/// 获取指令的时间戳,使用DataTime.Ticks获取
///

long Timestamp
{
get;
}


///
/// 获取指令的超时设定, 单位毫秒
///

int Timeout
{
get;
}
}

///
/// 空指令:什么也不做的指令
///

public class EmptyCmd : IDeviceCmd
{
public long Timestamp {
get {
return 0;
}
}

public int Timeout {
get {
return -1;
}
}


        public void Execute()
{
//do nothing;
}

public void Simulate()
{
//do nothing;
}
}

你可能感兴趣的:(C#消息队列原理)