TimerComponent学习笔记

TimerComponent

请大家关注我的微博:@NormanLin_BadPixel坏像素


Timer

public class Timer
    {
        public long Id { get; set; }
        public long Time { get; set; }
        public TaskCompletionSource<bool> tcs;
    }

我们在读别人代码的时候,要常常猜想别人写这个脚本是用来干什么的,而最方便的便是通过别人脚本的名称和方法的名称去猜(有注释的都是好人)。比如这个Timer,直译过来是计时器的意思。我们发现里面存放了一个TaskCompletionSource,这个东西我去百度了,这是c#异步编程里面的东西,之前也没有接触过,所以看了很多资料,不过对这个东西的介绍都不多,我们姑且认为它是一个可以控制任务(Task)完成的控制器。这个控制器里连接着一个任务。所以,我们这个计时器并不简单,更像是一个时间戳。具体什么用我们继续看下去。

接下来是定义了三个变量。

private readonly Dictionary<long, Timer> timers = new Dictionary<long, Timer>();
private readonly MultiMap<long, long> timeId = new MultiMap<long, long>();
private readonly EQueue<long> timeoutTimer = new EQueue<long>();

现在不知道具体是干嘛的,我们记住它们的类型就好了。这里有个新的家伙MultiMap,可能跟EQueue一样是作者鼓捣出来的东西。

MultiMap

神奇,这个类还是跟普通的Map不一样的。

首先,它是一个SortedDictionary,这是什么呢?讲真,我对C#的理解还是太缺少了,但是我可以不断去学习呀!这是一个以键排序的字典,而且键值是唯一的。也就是说,当插入或者移除的时候,这个字典会自动以键来排序。而普通的字典则是以值来排序的。这对储存时间戳来说,非常合适。

然后,它的值是一个List,这就可以在一个时刻储存多个任务。

最后,它还提供了一个获取值副本的方法。

/// <summary>
/// 不返回内部的list,copy一份出来
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public K[] GetAll(T t)
{
    List<K> list;
    this.dictionary.TryGetValue(t, out list);
    if (list == null)
    {
        return new K[0];
    }
    return list.ToArray();
}

个人觉得这个方法很有用,因为有些时候你只想对副本操作,而不改变原来的。如果每一个List都要自己写的话,很麻烦。

其他的一些内容我相信大家都看得懂,嘿嘿。回去。

TimerComponent

现在,我们得先知道这几个变量都是用来干什么的。所以,我们先找到在哪里给这些变量插入信息了。
先找到一个最简单的

public Task WaitTillAsync(long tillTime)
    {
        TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
        Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = tillTime, tcs = tcs };
        this.timers[timer.Id] = timer;
        this.timeId.Add(timer.Time, timer.Id);
        return tcs.Task;
    }

从这里我们就可以很容易看出来,timers是以Timer类型的变量的Id为键的,Timer类型的变量为值的一个字典。而timeId则是以Timer类型的变量的时间为键,List

public Task WaitAsync(long time)
    {
        TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
        Timer timer = new Timer { Id = IdGenerater.GenerateId(), Time = TimeHelper.Now() + time, tcs = tcs };
        this.timers[timer.Id] = timer;
        this.timeId.Add(timer.Time, timer.Id);
        return tcs.Task;
    }

这个跟之前的也和像,不过之前的是指定时刻,这个是指定延时,其实这段代码更符合我们之前举的例子。

我们看到,它分别被ClientFrameComponentResourcesComponent调用了。我们就去看看。
fuck,我想多了,这就是一个简单的计时器。
但是,大佬写出来肯定是有其道理的,不是我等小辈可以妄自揣测的。所以我屁颠屁颠去问了大佬。

大佬:嗯,就是类似Task.Delay的功能,不过因为每次使用Task.Delay都会占用一个线程池线程,性能太差,所以猫大自己写了一个

原来如此。我真的想多了。


结束语

不怕自己想多了,就怕自己不多想。 —————————————— NormanLin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值