线程中的定时器如何结束

BenBenBears 2014-09-22 03:55:40

static void Main(string[] args)
{
Thread ThrdA = new Thread(FunA);
ThrdA.Start();
Console.ReadLine();
}
public static void FunA()
{
Timer timerA = new Timer(new TimerCallback(A), null,0, 3000);
}
public static void A(object a)
{
Console.WriteLine("{0}", Thread.CurrentThread.ManagedThreadId);
}

这样的代码会一直正常输出Thread.CurrentThread.ManagedThreadId的值;

static void Main(string[] args)
{
Thread AThrd = new Thread(AutoAddFun);
Thread RThrd = new Thread(AutoReadFun);
AThrd.Start();
RThrd.Start();
Console.ReadLine();
}

static List<int> numList = new List<int>();

static ReaderWriterLock rwl = new ReaderWriterLock();

public static void AutoAddFun()
{
Timer timerAdd = new Timer(new TimerCallback(Add), null, 0, 3000);
}

public static void AutoReadFun()
{
Timer timerRead1 = new Timer(new TimerCallback(Read), null, 0, 1000);
Timer timerRead2 = new Timer(new TimerCallback(Read), null, 0, 1000);
Timer timerRead3 = new Timer(new TimerCallback(Read), null, 0, 1000);
}

public static void Add(object obj)
{
var num = new Random().Next(0, 1000);

rwl.AcquireWriterLock(TimeSpan.FromSeconds(30));

numList.Add(num);

Console.WriteLine("我是线程{0},我插入的数据是{1}。", Thread.CurrentThread.ManagedThreadId, num);

rwl.ReleaseWriterLock();
}

public static void Read(object obj)
{
rwl.AcquireReaderLock(TimeSpan.FromSeconds(30));

Console.WriteLine("我是线程{0},我读到的集合是{1}.", Thread.CurrentThread.ManagedThreadId, string.Join(",", numList));

rwl.ReleaseReaderLock();
}

这是@一线码农 的源码,讲解ReadWriterLock方面的知识点,运行代码一段时间后会停止输出,在所有定时器的回调函数中打了断点均没有中断,说明定时器已经停止了,在上下文中并没有主动将定时器停止,我想请问这个过程大概是怎样的。谢谢。
...全文
419 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
BenBenBears 2014-09-23
  • 打赏
  • 举报
回复
引用 8 楼 effun 的回复:
只要在使用 Timer,就必须保留对它的引用。 对于任何托管对象,如果没有对 Timer 的引用,计时器会被垃圾回收。 即使 Timer 仍处在活动状态,也会被回收。
是呀,@phommy的评论提醒了我往GC方面想,在@teof的博客上看到上面那句话,豁然开朗! 而且,回调方法不在创建计时器的线程上执行,而是在系统提供的ThreadPool线程上执行。呵呵
effun 2014-09-23
  • 打赏
  • 举报
回复
原因很简单,计时器被GC了。在MSDN里有一段话: 只要在使用 Timer,就必须保留对它的引用。 对于任何托管对象,如果没有对 Timer 的引用,计时器会被垃圾回收。 即使 Timer 仍处在活动状态,也会被回收。 http://msdn.microsoft.com/zh-cn/library/system.threading.timer(v=vs.110).aspx
BenBenBears 2014-09-23
  • 打赏
  • 举报
回复
引用 4 楼 Z65443344 的回复:
你确定这个代码是终止掉了,而不是进入死锁了?

        public static void Add(object obj)
        {
            var num = new Random().Next(0, 1000);
            try
            {
                rwl.AcquireWriterLock(TimeSpan.FromSeconds(30));
                try
                {
                    numList.Add(num);

                    Console.WriteLine("我是线程{0},我插入的数据是{1}。", Thread.CurrentThread.ManagedThreadId, num);
                }
                finally
                {
                    rwl.ReleaseWriterLock(); 
                }
            }
            catch (ApplicationException)
            {
                rwl.ReleaseWriterLock();
            }
        }
我修改了部分代码(同样修改了Read部分),如果死锁,请求便超时,同时抛出ApplicationException异常,实际上并没有抛出异常。所以,我想应该不是死锁的问题。
phommy 2014-09-23
  • 打赏
  • 举报
回复
凑巧而已,你测试时你的Timer正好没有被垃圾回收 试试改成这样,说不定Timer就不会继续跑了: var ThrdA = new Thread(FunA); ThrdA.Start(); for (int i = 0; i < 10; i++) { var s = new int[100000000]; } Console.ReadLine();
於黾 2014-09-23
  • 打赏
  • 举报
回复
所谓死锁,就是Add在等待Read,同时Read也在等待Add
於黾 2014-09-23
  • 打赏
  • 举报
回复
你确定这个代码是终止掉了,而不是进入死锁了?
BenBenBears 2014-09-23
  • 打赏
  • 举报
回复
锲而不舍
BenBenBears 2014-09-22
  • 打赏
  • 举报
回复
麻里麻里哄
BenBenBears 2014-09-22
  • 打赏
  • 举报
回复
浮起来!

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧