【发布时间】:2009-09-24 09:58:43
【问题描述】:
我有一个相当密集的方法,它接受给定的集合,复制项目(Item 类有正确定义的 Copy() 方法),用数据填充项目并将填充的集合返回到类的集合属性
//populate Collection containing 40 items
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );
此方法以两种方式调用:根据请求和通过 System.Timers.Timer 对象的“Elapsed”事件。
现在集合中的 40 件物品几乎不需要任何时间。无论是通过 button_click 填充“ad hoc”还是通过 Timer 对象填充。
现在,当我增加集合的大小(另一个具有 1000 个项目的 MyClass 对象)时,可以预见该过程需要更长的时间,但总共大约需要 6 秒。 很好,那里没有问题。在初始化时调用 (form_load) 或临时调用 (button_click),它会停留在 6 秒左右。
//populate Collection containing 1000 items
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );
但是,System.Timers.Timer 对象正在调用相同的方法(如在确切的代码行中)。而 Elapsed 大约需要 60 秒(其他运行 unclide 56 秒、1 分钟 2 秒、1 分钟 10 秒......你明白了)。 相同过程的十倍!
我知道 System.Timers.Timer 对象是在线程池中执行的。这可能是原因吗?是线程池的优先级较低还是整个排队都占用了时间?
简而言之,有什么更好的方法呢?使用 System.Windows.Forms.Timer 在同一个 UI 线程中执行?
谢谢!
好的,补充一些信息:
计时器操作发生在 UI 调用的 DLL 中。主“处理程序”类本身有一个定时器对象的集合,它们都订阅同一个事件处理程序。 处理程序类的初始化有点像这样:
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 控件的跨线程访问等),并在收到事件处理时显示。对于“初始化”和“临时”调用都是如此(在这些情况下没有问题)。
实际的 Elapsed 事件如下所示:
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);
}
}
【问题讨论】:
-
能否请您显示 Elapsed 事件处理程序的代码?
-
...还有一个你如何测量时间的样本,也许?
-
好的,所以我尝试过使用 System.Windows.Forms.Timer,不同之处就在于它。回到 6 秒。奇怪的是,我的 CPU(四核 2.4)在 System.Timers.Timer 对象正在运行但对 Windows.Forms.Timer 几乎没有闪烁时进行了艰苦的战斗(40%)。我现在可以继续使用 Forms.Timer 对象。有没有人对为什么 CPU 会与线程池中的某些东西如此激烈地斗争有更多的想法(我的意思是,池的想法不是让事情变得更快吗?)
标签: c# multithreading timer threadpool