Skip to content
ScutGame edited this page Jul 6, 2015 · 9 revisions

此章节介绍如何在服务端使用Timer定时器

提供CacheListener缓存定时、SyncTimer精确定时、TimeListener整点定时和EventNotifier事件异步等类处理定时、间隔或延迟业务。

使用线程注意

使用Timer定时器或新的子线程中调用脚本的方法,要使用ScriptEngines脚本引擎管理类调用指定脚本的方法;否则热更新时脚本修改不会生效; 以下脚本定时节的示例有调用方法

CacheListener缓存定时

不精确定时,一般在间隔多少分钟为单位时使用;使用例子:

static void Main()
{
    //间隔1分钟执行
    CacheListener cacheListener = new CacheListener("TestListener", 60, DoExecute);
    cacheListener.Start();
}

static void DoExecute(string key, object value, CacheRemovedReason cacheRemovedReason)
{
    //do something
}

SyncTimer精确定时

每次只允许一个线程执行,可设置执行超时时间;使用例子:

static void Main()
{
    //间隔1秒执行,延迟100毫秒开始启动,执行1分钟超时
    SyncTimer testTimer = new SyncTimer(DoExecute, 100, 1000, 60000);
    testTimer.Start();
}


private static void DoExecute(object state)
{
    //do something
}

在CsScript脚本中使用示例

当脚本热更新时,需要调用ScriptEngines.RuntimeScope.InvokeStaticMenthod方法,ScriptTimer脚本才会生效。

static void Main()
{
    //以SyncTimer为例,其它定时类相同
    SyncTimer testTimer = new SyncTimer(DoExecute, 100, 1000, 60000);
    testTimer.Start();
}

private static void DoExecute(object state)
{
    if (ScriptEngines.IsCompiling)
    {
        return;
    }
    //调用ScriptTimer脚本无参数无返回值的Execute1静态方法
    ScriptEngines.RuntimeScope.InvokeStaticMenthod<ScriptTimer>("Execute1");
    
    //调用ScriptTimer脚本无参数bool返回值的Execute2静态方法
    bool result;
    ScriptEngines.RuntimeScope.InvokeStaticMenthod<ScriptTimer, bool>("Execute2", out result);

    //调用ScriptTimer脚本带参数bool返回值的Execute3静态方法
    bool result;
    object[] args = new object[]{ 1001, "John"};
    ScriptEngines.RuntimeScope.InvokeStaticMenthod<ScriptTimer, bool>("Execute3", args, out result);

}

脚本中的ScriptTimer类,代码如下:

public class ScriptTimer
{
    public static void Execute1()
    {
        //do something
    }
    
    public static bool Execute2()
    {
        //do something
        return true;
    }
    
    public static bool Execute3(int code, string name)
    {
        //do something
        return true;
    }
}

TimeListener整点定时

有执行某个时间点单次处理任务,执行每天定点任务,执行指定开始到结束时间每间隔多少秒执行一次任务和每周执行任务;使用例子:

static void Main()
{
    //在2014-12-12那天9点执行一次,结束后任务被删除
    TimeListener.Append(PlanConfig.OncePlan(DoOnceExecute, "OncePlanTask",  "2014-12-12 09:00"));

    //每天0点执行
    TimeListener.Append(PlanConfig.EveryDayPlan(DoEveryDayExecute,  "EveryDayTask", "00:00"));

    //从20到22点时间范围内每隔30分钟执行
    TimeListener.Append(PlanConfig.EveryMinutePlan(DoEveryMinuteExecute, "EveryMinuteTask", "20:00", "22:00", 180));

    //在2014-12-12那天,从20到22点时间范围内每隔30分钟执行,结束后任务被删除
    TimeListener.Append(PlanConfig.EveryMinutePlan(DoEveryMinuteExecute, "EveryMinuteTask", "2014-12-12 20:00", "2014-12-12 22:00", 180));

    //每周星期五0点执行一次
    TimeListener.Append(PlanConfig.EveryWeekPlan(DoEveryWeekExecute, "EveryWeekTask", DayOfWeek.Friday, "00:00"));

}

private static void DoOnceExecute(PlanConfig planconfig)
{
    if (ScriptEngines.IsCompiling)
    {
        return;
    }
    //do something
}

private static void DoEveryDayExecute(PlanConfig planconfig)
{
    if (ScriptEngines.IsCompiling)
    {
        return;
    }
    //do something
}

private static void DoEveryMinuteExecute(PlanConfig planconfig)
{
    if (ScriptEngines.IsCompiling)
    {
        return;
    }
    //do something
}

private static void DoEveryWeekExecute(PlanConfig planconfig)
{
    if (ScriptEngines.IsCompiling)
    {
        return;
    }
    //do something
}

EventNotifier事件

可以处理异步方法,或指定延迟时间回调处理方法,示例如下:

static void Main()
{
    //异步方法
    var e1 = new NotifyEventArgs();
    e1.Callback += (p) =>
    {
        //这里处理延迟逻辑
    };
    
    //延迟60s
    var e2 = new TimeoutNotifyEventArgs(60);
    e2.Callback += (p) =>
    {
        //这里处理延迟逻辑
    };
    //放入事件通知池,等待触发
    EventNotifier.Put(e1);
    EventNotifier.Put(e2);
    
}
Clone this wiki locally