V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
luent
V2EX  ›  问与答

C# 公共 Hashtable 变量在一个 System.Timers.Timer 中能改变值,但是 remove 后,下次为什么还有啊?

  •  
  •   luent · 2015-04-09 16:01:29 +08:00 · 2292 次点击
    这是一个创建于 3521 天前的主题,其中的信息可能已经有所发展或是发生改变。
    变量: public volatile static Hashtable M_Status = Hashtable.Synchronized(new Hashtable());
    太诡异了,郁闷啊!
    4 条回复    2015-04-10 00:06:56 +08:00
    caoyue
        1
    caoyue  
       2015-04-09 17:36:25 +08:00
    贴个完整点的代码比较方便看问题吧=-=
    dong3580
        2
    dong3580  
       2015-04-09 17:52:08 +08:00
    static
    dong3580
        3
    dong3580  
       2015-04-09 18:10:18 +08:00
    抱歉回复错了:
    System.Timers.Timer 还没执行已经输出结果了,也就是hashtable还没移除键值对,已经输出结果了。
    可以加个睡觉1s就正常。

    #####写个简单的eg:

    ''' C#
    public static Hashtable M_Status= Hashtable.Synchronized(new Hashtable());
    static void Main(string[] args)
    {
    M_Status = Hashtable.Synchronized(new Hashtable());
    M_Status.Add("a", "a");
    M_Status.Add("b", "b");
    Timer t = new Timer();
    t.Elapsed += t_Elapsed;
    t.Start();
    //System.Threading.Thread.Sleep(1000);
    Console.Write(M_Status.Count.ToString());
    Console.ReadLine();
    }

    static void t_Elapsed(object sender, ElapsedEventArgs e)
    {
    M_Status.Remove("a");
    }
    '''
    hiro0729
        4
    hiro0729  
       2015-04-10 00:06:56 +08:00
    Timer 的本质是线程啊,t.Start()开始一个新线程。也就是说,t.Start()并不一定是马上执行的,需要看系统对线程的分配。

    //System.Threading.Thread.Sleep(1000);强制睡眠当前线程时,新线程肯定就能运行了,能正确删除a。
    如果在Console.Write(M_Status.Count.ToString());之前没有大量耗时运算或切换线程的操作的话,大概率是Timer的事件还没运行,这边就已经运行结束了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1122 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 19:20 · PVG 03:20 · LAX 11:20 · JFK 14:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.