附注:
全部代码贴在下面,也可以从以下地址下载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 环境下,都是一样。
问题:
难道定时器受到内存的限制?
程序清单:
//
// 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( " 第 " + _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();
}
}
}
// 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( " 第 " + _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();
}
}
}