在 Visual Studio 和 .NET Framework 中有三种计时器控件:
基于服务器的计时器(可以在“工具箱”的“组件”选项卡上看到)(System.Timers.Timer)
基于 Windows 的标准计时器(可以在“工具箱”的“Windows 窗体”选项卡上看到)(System.Windows.Forum.Timer)
线程计时器(只能以编程方式使用)。(System.Threading.Timer )
System.Windows.Forum.Timer
基于 Windows 的计时器从 Visual Basic 1.0 版起就存在于该产品中,并且基本上未做改动。该计时器针对在 Windows 窗体应用程序中使用而进行了优化。
System.Timers.Timer
基于服务器的计时器是传统的计时器为了在服务器环境上运行而优化后的更新版本。
System.Threading.Timer
线程计时器是一种简单的、轻量级计时器,它使用回调方法而不是使用事件,并由线程池线程提供支持。
在 Win32 体系结构中有两种类型的线程:
UI 线程和辅助线程。UI 线程绝大多数时间处于空闲状态,等待消息循环中的消息到来。
一旦接收到消息,它们就进行处理并等待下一个消息到来。
另外,辅助线程用来执行后台处理而且不使用消息循环。
Windows 计时器和基于服务器的计时器在运行时都使用 Interval 属性。
线程计时器的时间间隔在 Timer 构造函数中设置。
计时器的设计目的各不相同,它们的线程处理明确地指出了这一点:
-
Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。Windows 计时器的精度限定为 55 毫秒。这些传统计时器要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。对于 COM 组件来说,这样会降低性能。
-
基于服务器的计时器是为在多线程环境下与辅助线程一起使用而设计的。由于它们使用不同的体系结构,因此基于服务器的计时器可能比 Windows 计时器精确得多。服务器计时器可以在线程之间移动来处理引发的事件。
-
对消息不在线程上发送的方案中,线程计时器是非常有用的。例如,基于 Windows 的计时器依赖于操作系统计时器的支持,如果不在线程上发送消息,与计时器相关的事件将不会发生。在这种情况下,线程计时器就非常有用。
Windows 计时器位于 System.Windows.Forms 命名空间中,
服务器计时器 System.Timers 命名空间中,
线程计时器位于 System.Threading 命名空间中。
参考:
http://msdn2.microsoft.com/zh-cn/library/tb9yt5e6(VS.80).aspx
先不看任何结论分析,先看两个例子:
Web程序场景A :
此web程序 包含其中这样一个类:
public class StaticClass
{
static StaticClass()
{
// 函数 1
int bb = 1;
}
public StaticClass()
{
// 函数 2
int aa = 1;
}
public static string AAA = Test();
public static string Test()
{
// 函数 3
return "aaa";
}
public static string Test2()
{
// 函数 4
return "aaabbb";
}
}
同时,这个 Web 程序的 Global.asax 文件中有如下定义
void Application_Start(object sender, EventArgs e)
{
// 函数 5
string tt = StaticClass.AAA;
}
问:上述涉及到的几个函数在打开一个Web页面的时候,那个先被执行??
注:你可以建立这样一个简单的 Web 项目或站点,然后每个函数增加一个断点,开始调试并执行,就可以看到每个函数被执行的先后顺序。
我自己Vista64位操作系统,VS2005+VS2005自带的 ASP.Net Development Server 开发站点
测试的执行顺序如下:
函数5 --〉 函数3 --〉 函数1
Web程序场景B :
上述 StaticClass 类中,删除函数1、函数2这两个函数,然后作同样的试验。这个类变成了如下代码:
public class StaticClass
{
public static string AAA = Test();
public static string Test()
{
// 函数 3
return "aaa";
}
public static string Test2()
{
// 函数 4
return "aaabbb";
}
}
这时候测试的执行结果是:
函数3 --> 函数5
小结:
现象:
有无静态构造函数,导致 Application_Start 和 类的静态属性执行顺序发生变化。
无静态构造函数,类的静态属性先被执行
有静态构造函数,Application_Start 先被执行
如果涉及到静态构造函数、类的静态属性的执行顺序时候要非常小心。
公司前不久一个同事写的代码中,在类的静态属性中做一些初始化填充数据的操作,
但是这些操作是上述场景B的情况,
这个初始化工作是Application_Start之前执行的,当然就无论如何都无法初始化数据了。
参考资料:
静态构造函数
http://blog.joycode.com/ghj/archive/2004/08/24/31504.aspx
前几天公司运维组的由于公司一台服务器中毒了,强制把公司所有服务器都装了经典的杀毒软件 Macfee VirusScan Enterprise 8.0i 。 结果一系列的问题都出来了。
单单跟我们组有关的 http://community.csdn.net http://topic.csdn.net 这两台服务器,都时不时出现下面的错误。停掉并卸载杀毒软件后,一切都恢复正常了。
下面罗列一下我们中间碰到的一些错误信息,当你碰到这样的错误信息时候,可能也跟我们一样,是因为服务器上杀毒软件的原因导致的。
ASP 程序产生的错误:
错误1:
Active Server Pages 错误 'ASP 0240'
脚本引擎异常
/t/20040401/11/2912553.html
ScriptEngine 产生了异常 'C0000005'(错误位于 'IActiveScriptParse::ParseScriptText()' 中,来自 'CActiveScriptEngine::AddScriptlet()')。
错误2:
msxml3.dll 错误 '8007000e'
存储空间不足,无法完成此操作。
******.asp , 行 176
错误3:
Microsoft OLE DB Provider for SQL Server 错误'80004005'
[DBNETLIB][ConnectionOpen (SECDoClientHandshake()),]SSL 安全错误。
******.asp , 行 7
错误4:
Microsoft VBScript 运行时错误 错误 '800a0007'
内存不够: 'LCase'
********.asp,行 10
错误5:
Microsoft OLE DB Provider for SQL Server 错误 '80004005'
[DBNETLIB][ConnectionOpen (ConnectionOpen()()).]一般性网络错误。请检查网络文档。
****.asp,行 7
错误6:
Provider 错误 '80004005'
未指定的错误
*****.asp,行 7
ASP.net 的错误
错误1:
System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常。
Generated: Thu, 04 Jan 2007 10:32:55 GMT
System.Configuration.ConfigurationErrorsException: 引发类型为“System.OutOfMemoryException”的异常。 ---> System.OutOfMemoryException: 引发类型为“System.OutOfMemoryException”的异常。
在 System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
在 System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
在 System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
在 System.Reflection.Assembly.Load(String assemblyString)
在 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)
--- 内部异常堆栈跟踪的结尾 ---
在 System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective)
在 System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory()
在 System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai)
在 System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig)
在 System.Web.Compilation.WebDirectoryBatchCompiler..ctor(VirtualDirectory vdir)
在 System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(VirtualDirectory vdir, Boolean ignoreErrors)
在 System.Web.Compilation.BuildManager.BatchCompileWebDirectory(VirtualDirectory vdir, VirtualPath virtualDir, Boolean ignoreErrors)
在 System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
在 System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)
在 System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)
在 System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
在 System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp, Boolean noAssert)
在 System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
在 System.Web.UI.PageHandlerFactory.System.Web.IHttpHandlerFactory2.GetHandler(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
在 System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, VirtualPath path, String pathTranslated, Boolean useAppConfig)
在 System.Web.HttpApplication.MapHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
在 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)