V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
luent
V2EX  ›  问与答

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

  •  
  •   luent · Apr 9, 2015 · 2899 views
    This topic created in 4049 days ago, the information mentioned may be changed or developed.
    变量: public volatile static Hashtable M_Status = Hashtable.Synchronized(new Hashtable());
    太诡异了,郁闷啊!
    4 replies    2015-04-10 00:06:56 +08:00
    caoyue
        1
    caoyue  
       Apr 9, 2015
    贴个完整点的代码比较方便看问题吧=-=
    dong3580
        2
    dong3580  
       Apr 9, 2015
    static
    dong3580
        3
    dong3580  
       Apr 9, 2015
    抱歉回复错了:
    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  
       Apr 10, 2015
    Timer 的本质是线程啊,t.Start()开始一个新线程。也就是说,t.Start()并不一定是马上执行的,需要看系统对线程的分配。

    //System.Threading.Thread.Sleep(1000);强制睡眠当前线程时,新线程肯定就能运行了,能正确删除a。
    如果在Console.Write(M_Status.Count.ToString());之前没有大量耗时运算或切换线程的操作的话,大概率是Timer的事件还没运行,这边就已经运行结束了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5777 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 03:45 · PVG 11:45 · LAX 20:45 · JFK 23:45
    ♥ Do have faith in what you're doing.