附注:
全部代码贴在下面,也可以从以下地址下载VS2003 Project:http://zhangleixp.itpub.net/get/13774/WeirdTimer_SRC.rar。程序说明:
1、Start 方法可以有两种方式启动Do方法:
第一种是使用定时器,
第二种是不使用定时器,直接用一个while(true)循环。
2、该程序是为了更清楚的演示问题而建立,其中创建StringBuilder对象只是为了占用内存而已。奇怪现象:
1、如果使用定时器方式,则(以下数据,不同机器上稍不相同,同一机器上有时也不相同)
当_objectSize = 100  时,Do方法被执行大约175次; 
当_objectSize = 1000 时,Do方法被执行大约33次;
当_objectSize = 10000时,Do方法被执行大约4次。
2、如果不使用定时器,就不存在上述的问题,Do方法会一直被执行下去,没有次数的限制。
3、在Visual Studio 2003 和 Visual Studio 2005 环境下,都是一样。问题:
难道定时器受到内存的限制?程序清单:
//
// File Name: Worker.cs
//
using System;
using System.Text;
using System.Threading;
using System.Collections;namespace WeirdTimer
{
    public class Worker
    {
        /// <summary>
        /// 创建的对象的计数。
        /// </summary>
        int _objectCount = 0;        /// <summary>
        /// Do 方法执行的次数。
        /// </summary>
        int _doCount = 0;        /// <summary>
        /// 链表,用于保存创建对象的引用。
        /// </summary>
        ArrayList _list = new ArrayList();        /// <summary>
        /// 对象的所占内存空间的大小。(字符数)
        /// </summary>
        int _objectSize = 10000;        /// <summary>
        /// 是否使用定时器。
        /// </summary>
        public static bool IsTimerUsed = true;
        /// <summary>
        /// Do 方法。作为Timer 的回调函数。
        /// </summary>
        public void Do(object obj)
        {
            ++_doCount;
            Console.WriteLine("第" + _doCount.ToString() + "次执行Do 方法。");            for(int i = 0; i < 3; i++)  // 每次执行Do 创建3 个StringBuilder 对象。
            {
                StringBuilder sb = new StringBuilder(_objectSize);
                _list.Add(sb);                ++_objectCount;                Console.WriteLine("\t\t第" + _objectCount.ToString() + " 个对象已创建。");
            }
        }        /// <summary>
        /// 启动Do 操作。
        /// </summary>
        public void Start()
        {
            if(Worker.IsTimerUsed) // 定时器方式
            {
                TimerCallback callback = new TimerCallback(Do);
                Timer timer = new Timer(callback, null, 0, 500);
            }
            else // 非定时器方式
            {
                while(true)
                {
                    Do(null);
                }
            }
        }        public static void Main()
        {
            Console.WriteLine("按回车键退出程序...");
            Worker aWorker = new Worker();
            aWorker.Start();
            Console.ReadLine();
        }
    }
}

解决方案 »

  1.   

    贴到BLOG上了,代码看起来舒服一点。
    http://blog.csdn.net/zhangleixp/archive/2006/08/02/1009535.aspx大家最好在论坛这儿回帖,便于给分。
      

  2.   

    没仔细看 说说可能的原因
    while(true)
       Do(null);
    执行这句的时候 程序会按标准的顺序执行 也就是说一个do结束后才运行另一个
    当使用timer 因为有个回调,我不确定当第二次执行的时候 第一个do是否运行完毕,是使第二无效还是第一次的执行被复位。 会的不多 见谅
      

  3.   

    只要在使用 Timer,就必须保留对它的引用。对于任何托管对象,如果没有对 Timer 的引用,计时器会被垃圾回收。即使 Timer 仍处在活动状态,也会被回收。
      

  4.   

    代码改一下
    /// </summary>
    public void Start()
    {
    if(Worker.IsTimerUsed) // 定时器方式
    {
    callback = new TimerCallback(Do);
    timer = new Timer(callback, null, 0, 500);
    }
    else // 非定时器方式
    {
    while(true)
    {
    Do(null);
    }
    }
    } public static void Main()
    {
    Console.WriteLine("按回车键退出程序...");
    Worker aWorker = new Worker();
    aWorker.Start();
    Console.ReadLine();
    }
    static TimerCallback callback; 
    static Timer timer;//把timer的申明改在这
      

  5.   

    hdt(倦怠) 正确!
    散分!谢谢!