« 今天作了什么? | Main | blog之随感 »

从timer看一眼.net的编译机制

作者:virushuo 发表于 2003-12-26 12:12 最后更新于 2005-10-14 16:10
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明


    因为工作需要,制作了一个定时发送数据的windows service,C#开发。其中碰上了一个很有意思的问题。


 


先看看程序大概的结构:


 


初始化


              private void InitializeComponent()

              {

                     this.timer1 = new Timer();

                     this.timer1.Elapsed += new ElapsedEventHandler(timer1_Tick);

              }

       serviceonStart() 

protected override void OnStart(string[] args)

              {

                     timer1.Interval = 6000;

                     timer1.Start();

                     EventLog.WriteEntry(ServiceName +"Event","timer started 1");

              }

定时器触发

              private void timer1_Tick(Object source, ElapsedEventArgs e)

              {

                     DateTime time = DateTime.Now;

                     TimeSpan dayspan=new  TimeSpan(1,0,0,0);

                     time=time.Subtract(dayspan);

                     DateTime dateTime1=new DateTime(time.Year,time.Month,time.Day,0,0,0);

                     DateTime dateTime2=new DateTime(time.Year,time.Month,time.Day,23,59,59);

                    

                     if (time.Hour==8&&time.Minute==30&&lastupdate.Day!=DateTime.Now.Day)

                     {

                           

try


                           
{


                                  
PSOInterfaceWraper PsoWraper = new PSOInterfaceWraper();


                                  
PSOInterfaceWraper.GeneralLedgerAsyncResult Result;


 


                                  
DateTime StartDate=dateTime1;


                                  
DateTime EndDate=dateTime2;

                                   int amount=LedgerAsyncBLL(StartDate,EndDate);

                                   Result = PsoWraper.GeneralLedgerAsync("00",StartDate,EndDate,this.TranslationCount,amount*100);               

                           

                                   EventLog.WriteEntry(ServiceName +" Vnet","Result:"+ Result.Result+"  "+Result.ErrorDescription+"Count:"+this.TranslationCount.ToString()+"---Amount:"+(amount*100).ToString()+"  date:"+StartDate.ToString()+"~"+EndDate.ToString());

                                   if (Result.Result==0)

                                          lastupdate= DateTime.Now;

                            }

                            catch (Exception err)

                            {

                                   EventLog.WriteEntry(ServiceName +" Vnet","Error:"+"  "+err.Message);

                            }

                     }

              }

             

实际运行中发现,       EventLog.WriteEntry(ServiceName +"Event","timer started 1"); 运行正确,但是timer1_Tick中的代码并没有运行。

后来分析发现,工程的Refences中引用了VNetPSO.dll,但是没有把相应的文件copy,到相应目录。也就是说,运行时找不到此文件。

观察代码可知,引用VNetPSO.dll部分的代码只存在于timer1_Tick中。复制VNetPSO.dll到正确位置,问题排除。

由此发现.net所谓即时编译的一些特性。

InitializeComponent()中,可看到this.timer1.Elapsed += new  lapsedEventHandler(timer1_Tick);按照.net的即时编译的思路,开始认为这段代码会导致timer1_Tick被编译。但是如果是这样的顺序,在InitializeComponent中就会出现错误,导致程序不能正常运行。_那么OnStartEventLog.WriteEntry(ServiceName +"Event","timer started 1");

也就不可能运行了。

     所以,timer1_Tick实际是在Timer第一次触发的时候才被编译的。上面程序的例子中,就是在timer1启动了6秒之后。这时候发现VNetPSO.dll不存在,故此这部分代码被编译器忽略。也就造成了最开始出现的情况。

当然,前面只是一些推测,并没有方法能得到可靠的验证。但是,我认为推测应该基本合理。

至少,可以推测这么几个事实:

1 .net中的代码只有实际用到才会编译,除非强制进行预编译。

2 由于以上机制定时器变得更加不可靠,因为在定时器第一次触发的瞬间会导致编译,对于要求时间很高的程序可能会导致错过第一次执行的时间。

Tags:
以下文章供您参考:

从SOA说开去 - Mar 10, 2008

德国式的幽默 - Mar 06, 2008

说总是比做容易 - Mar 03, 2008

TrackBack

TrackBack URL for this entry:
http://www.devep.net/cgi-bin/mt/devtb.pl/7

Comments

问题1,webform也是如此?恐怕不是,记得有一次,我更改了用户登录部分的代码,没有编译,然后就运行,结果到了那里提示出错。

问题2,定时触发。huo记得上次我说的我们学校工作日志的那个OA么,最后我把定时系统自动添加空日志做出来了,用了sql的作业,定时运行一个比较复杂的sql插入语句。搞定了。所以,我想,这个应该是驻留内存的程序监视系统时间,用此去激发一个事件。这样应该可以解决问题。

我要做的不是定时执行个sql语句这么简单。所以不能靠sql server。
现在功能已经实现了,但是这个错误引出的.net动态编译机制的问题让我有了点兴趣,打算挖一挖。

webform应该也是。虽然我还没有测试。

我不是说定时执行个sql语句。我是说些一个程序驻留内存...

Post a comment


about me:
me.jpg
CC License. Some rights reserved.
署名·非商业用途·保持一致
本站之所有未作特别说明的内容均使用 创作共用协议.
POWERED_BY_MT_3.2