2009-09-24 24 views
0

我有一個相當的流程密集型方法,它採用給定的集合,複製項目(Item類具有正確定義的其Copy()方法),填充數據項,並返回填充集合類的集合屬性System.Timers.Timer經過10倍的時間執行比Button_click

//populate Collection containing 40 items 
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems); 

這種方法被稱爲有兩種方式:根據要求,並通過System.Timers.Timer對象的「已用」事件。

集合中的40個項目幾乎沒有時間。無論是通過說button_click還是由Timer對象填充「填充」。

現在,當我增加集合的大小(另一個MyClass對象有1000個項目)時,該過程可預測花費更長時間,但總共大約需要6秒。 這很好,沒有問題。被調用初始化(form_load)或被稱爲臨時(button_click)它保持約6秒。

//populate Collection containing 1000 items 
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems); 

但是,同樣的方法(如在代碼中的特定行)正在由System.Timers.Timer對象調用。而且Elapsed大概需要60秒(其他的運行方式不需要56秒,1分鐘2秒,1分10秒......你會明白這一點)。 相同過程的十倍!

我知道System.Timers.Timer對象在線程池中執行。這可能是原因嗎?線程池的優先級較低還是整個排隊的事情佔用了時間?

總之,對此有更好的方法是什麼?使用System.Windows.Forms.Timer在相同的UI線程中執行?

謝謝!

好,一些附加的信息:

定時器操作一個DLL內發生由UI被調用。主'處理器'類本身具有一組定時器對象,它們都訂閱相同的事件處理程序。 處理程序類的初始化工作有點像這樣:

UpdateIntervalTimer tmr = new UpdateIntervalTimer(indexPosition); 
tmr.Interval = MyClass.UpdateInterval * 60000; //Time in minutes 
tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed); 
this.listIntervalTimers.Add(tmr); 

我其實是繼承了Timer類,給它一個‘索引’屬性(EventArgs的爲好)。這種方式在一個事件處理程序(tmr_Elapsed)中,我可以識別定時器的MyClass對象並採取行動。

處理程序類已在其自己的線程中運行,並觸發自定義事件以提供對其操作的洞察。 事件在UI中進行處理(UI控件的交叉線程訪問和whatnot),並顯示處理事件的時間。對於'初始化'和'臨時'調用都是如此(在這些情況下沒有問題)。

實際用掉的事件如下所示:

private void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
      UpdateIntervalTimer tmr; 
      tmr = (UpdateIntervalTimer)sender; 

      MyClass c = listOfClasses[tmr.IndexPosition]; 

      observerEventArguments = new MyHandlerEventArgs("Timer is updating data for " + MyClass.ID); 
      MessagePosted(this, observerEventArguments); 

      try 
      { 
       //preparation related code 


       MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems); 


       observerEventArguments = new ProfileObserverEventArgs(MyClass.ID + ": Data successfully updated"); 
       MessagePosted(this, observerEventArguments); 
      } 
      catch (Exception exUpdateData) 
      { 
       observerEventArguments = new MyHandlerEventArgs("There was an error updating the data for '" + MyClass.ID + "': " + exUpdateData.Message); 
       MessagePosted(this, observerEventArguments); 
      } 
     } 
+0

能否請您展示經過的事件處理程序的代碼? – 2009-09-24 10:01:35

+0

...而且你如何衡量TI的樣本我,也許? – 2009-09-24 10:02:53

+1

好吧,所以我試過使用System.Windows.Forms.Timer,區別只是重擊。回到6秒。奇怪的是,當System.Timers.Timer對象運行時,我的CPU(Quad core 2.4)正在努力(40%),但對於Windows.Forms.Timer卻幾乎沒有閃現。 我現在可以繼續使用Forms.Timer對象。有沒有人有更多的想法,爲什麼一個CPU會的東西這麼難打的線程池(我的意思是,心不是池中,使事情更快的主意嗎?) – MoSlo 2009-09-24 15:13:23

回答

1

好了,UI線程可能有更高的優先級 - 畢竟,它的意思是保持UI響應。然而,還有其他的事情可能會發生。您的方法是否以線程安全的方式訪問UI?如果是這樣,顯然它會更快,因爲它不需要在線程之間編組。

你可以嘗試拉動了線程池線程的優先級,看看是否能提高性能 - 但除此之外,我們還需要更多的信息。

不會勸你做到這一點的UI線程 - 掛在UI 6秒不使一個很好的用戶體驗:(

+0

好吧,這需要進一步研究,但使用System.Windows .Forms.Timer現在可以。我將不得不努力優化流程本身或者與優先級一起玩。 – MoSlo 2009-10-03 08:28:59

0

是區間流逝而你還在做工作的計時器,使其同樣的工作多次嗎?這是我能想到的是,UI定時器工作比system.timers.timer/system.threading.timer更快的唯一原因,因爲UI計時器是單線程直到它完成,不能再過去,而其他人可以。

+0

我明白你的論點,但定時器設置爲15分鐘。我有一個線程安全的列表框給出了代碼中發生的事情的輸出;所做的工作絕對在下一個Tick(或Elapsed)事件中。我可能不得不看一個多線程解決方案,而不是線程池解決方案。 – MoSlo 2009-12-17 07:39:09

相關問題