C# 浅谈事件监听及任务处理(监听属性值的改变及定时执行任务)

有些新手说我写的比较复杂,想要点简单又实用的东西,而是就写下了这篇文章...,老鸟直接跳过.

在很项目中都涉及到事件监听及任务处理的代码,例如:想监听一个网络状态,就像QQ一样,一但网线一拨,它马上就弹出连接网络失败类似的东东,虽然我没深入了解QQ用的是什么原理,但下面的代码却可以实现一样的功能,各位如有更好的方法,欢迎讨论。

 

先上一段监听属性值的的代码

新建一个DoEvent.cs类

using System;
using System.Web;

namespace VvxT.Web
{
    public class DoEvent
    {
        //需要监控的字段
        private static int currentState = -1;

        /// <summary>
        /// 构造函数
        /// </summary>
        public DoEvent()
        {
            OnMyStateChanged += new MyStateChanged(DoEvent_BeforeStateChanged);
        }

        //定义一个委托
        private delegate void MyStateChanged(object sender, EventArgs e);
        //定义一个委托关链的事件
        private event MyStateChanged OnMyStateChanged;

        //事件处理函数,属性值修改前的操作法
        private void DoEvent_BeforeStateChanged(object sender, EventArgs e)
        {
            //do something
        }

        //事件触发函数
        private void WhenMyStateChange()
        {
            if (OnMyStateChanged != null)
            {
                OnMyStateChanged(this, null);
            }
        }

        //属性设置,提供给外部修改触发
        public int MyState
        {
            get { return currentState; }
            set
            {
                //如果值发生变化则调用事件触发函数
                if (value != currentState)
                {
                    WhenMyStateChange();
                }
                currentState = value;
            }
        }
    }
}

 

 

例用示例:

代码很简单,我们先在DoEvent_BeforeStateChanged事件中打一个断点,然后我们再新建一个使用这个类的页面Default.aspx,然后在Page_Load事件里加入DoEvent myEvent = new DoEvent();

以下是

Default.aspx.cs代码

using System;
using System.Web;
using System.Web.UI;

namespace VvxT.Web
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            DoEvent myEvent = new DoEvent();
        }
    }
}

 

 

我们在DoEvent myEvent = new DoEvent();中也打一个断点以方便调试

好了,运行后会跳到你的断点处,我们按F10往下跳,然后在即时窗口里输入myEvent.MyState = 1;这个值随意输入,只要第一次不是0即可,发现程序己跳至DoEvent_BeforeStateChanged,在里面打上你要执行的一些东东,over

 

接下来是做一个带任务的,这个一看就是我一改变currentState的值就马上触发了我的DoEvent_BeforeStateChanged事件,可有时候项目中会有用到延时的操作,我们这里看做是任务

 

我们把上面的代码修改如下:

using System;
using System.Web;
using System.Timers;

namespace VvxT.Web
{
    public class DoEvent
    {
        //需要监控的当前状态属性
        private static int currentState = -1;
        //主动监控的状态保留属性
        private static int oldState = currentState;
        //主动监控的Timer
        Timer timer;

        /// <summary>
        /// 初始化默认值并绑定事件处理函数
        /// </summary>
        /// <param name="interval">默认值可为空(单位为毫秒)</param>
        public DoEvent(int? interval)
        {
            interval = interval ?? 5000;
            OnMyStateChanged += new MyStateChanged(DoEvent_BeforeStateChanged);
            timer = new Timer((int)interval);
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        }

        private void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            //如果值发生变化则调用事件触发函数
            if (currentState != oldState)
            {
                oldState = currentState;
                timer.Enabled = false;//暂停监控
                DoTaskWork();//做你的任务
                timer.Enabled = true;//继续监控
            }
        }

        //我的延时任务(例如定时到每天晚上4:00生成耗时的索引)
        private void DoTaskWork()
        {
            //do something
        }

        //定义一个委托
        private delegate void MyStateChanged(object sender, EventArgs e);
        //定义一个委托关链的事件
        private event MyStateChanged OnMyStateChanged;

        //事件处理函数,属性值修改前的操作法
        private void DoEvent_BeforeStateChanged(object sender, EventArgs e)
        {
            //do something
        }

        //事件触发函数
        private void WhenMyStateChange()
        {
            if (OnMyStateChanged != null)
            {
                OnMyStateChanged(this, null);
                //任务监听启动
                timer.Enabled = true;
            }
        }

        //属性设置,提供给外部修改触发
        public int MyState
        {
            get { return currentState; }
            set
            {
                //如果值发生变化前则调用事件触发函数(2011.1.7补充说明:大家可以随意调整位置,移下一行代码则就变成改变值后触发。)
                if (currentState != value)
                {
                    WhenMyStateChange();
                }
                currentState = value;
            }
        }
    }
}

 

 

因为延时执行任务会有一个时间,所以我们要改一下调用的方法,改为DoEvent myEvent = new DoEvent(null); 为null时默认为5秒后执行你的任务,也可以直接输入参数,例如:1小时=1*3600*1000 = 3600000,调试方法同上

如果你只要任务而不要属性值监听就相DoEvent_BeforeStateChanged相关的代码删除即可。也可以做成单一任务,即没有任何触发事件的,像每天晚上4:00生成索引或HTML什么的,就一般放在在应用程序启动时就实例化它,在结束就释放它即可,如不懂的欢迎讨论!

 

最后说一下,发个贴真不容易啊,真佩服那些有海量帖子的朋友啊!

 

 

 

posted @ 2011-01-06 22:13  varvery  阅读(10502)  评论(9编辑  收藏  举报