0

我有一个相当流程密集型的方法,它采用给定的集合,复制项目(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)或被称为 ad hoc(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);
            }
        }
4

2 回答 2

1

好吧,UI 线程可能具有更高的优先级 - 毕竟,它旨在保持 UI 响应。但是,还有其他可能发生的事情。您的方法是否以线程安全的方式访问 UI?如果是这样,显然当它不需要在线程之间编组时它会更快。

您可以尝试提高线程池线程的优先级,看看是否能提高性能——但除此之外,我们还需要更多信息。

建议您在 UI 线程上执行此操作 - 将 UI 挂起 6 秒并不能带来良好的用户体验 :(

于 2009-09-24T10:14:18.470 回答
0

当您仍在计时器中工作时,间隔是否已经过去,导致它多次执行相同的工作?这是我认为 UI 计时器比 system.timers.timer/system.threading.timer 工作得更快的唯一原因,因为 UI 计时器是单线程的,并且在完成之前不能再次过去,而其他计时器可以。

于 2009-12-15T23:00:39.470 回答