c# - 在计时器tick上执行多个线程

时间:2015-04-23 20:50:20

标签: c# multithreading winforms timer .net-3.5

我有一个程序,它有一个每秒钟滴答一次的计时器,每次打勾我需要多次执行一个方法。我想在自己的线程中调用每个方法。我调用的方法做了很多工作,并以webservice调用结束,因此可能需要一些时间才能完成(0-30秒)。我不需要收集回复,所以它基本上是开火而忘记了。

问题是如果该方法需要被调用,例如每秒5次,它只会被调用1-2次,其余部分将被忽略,因为新的计时器标记将被触发。

我正在使用.net 3.5,winforms和df$yy <- with(df, time* outcome) df$ll <- with(df, ave(id, id, FUN=length)) df$temp <- with(df, outcome==1 & yy != ll) df$warn <- with(df, ave(temp, id, FUN=function(X) any(X))) df # id time outcome yy ll temp warn # 1 1 1 0 0 3 FALSE FALSE # 2 1 2 0 0 3 FALSE FALSE # 3 1 3 0 0 3 FALSE FALSE # 4 2 1 0 0 3 FALSE FALSE # 5 2 2 0 0 3 FALSE FALSE # 6 2 3 1 3 3 FALSE FALSE # 7 3 1 0 0 3 FALSE TRUE # 8 3 2 1 2 3 TRUE TRUE # 9 3 3 0 0 3 FALSE TRUE # 10 4 1 0 0 3 FALSE TRUE # 11 4 2 1 2 3 TRUE TRUE # 12 4 3 1 3 3 FALSE TRUE

知道如何确保在每个计时器滴答时执行所有方法调用吗?

如果需要,我可以发布源代码。

由于

2 个答案:

答案 0 :(得分:1)

多线程环境中的主要问题是,您无法保证已启动的工作项将在您启动的时间内执行。

有一些线程会冻结的原因很多:优先级较高的新线程,CPU错误,异常等等。因此,即使您使用ThreadPool.QueueUserWorkItem开始工作,也无法保证ThreadPool能够以这种方式正确执行。

首先,请注意ThreadPool.QueueUserWorkItem每次都不会创建新的主题。 ThreadPool很可能会等待现有线程完成它的工作,并再次使用它。默认情况下,ThreadPool使用的内部线程数等于机器上的内核数 - 这种方法可以最大限度地减少线程之间的上下文切换。

其次,如果你说工作线程需要完成很长时间,而你每秒创建5个新请求,用户机器很快就会遇到饥饿问题 - 会有很多工作项使用固定数量的线程执行,您的应用程序将在上下文切换中死亡。

因此,我建议您使用FIFO队列作为工作项,并存储启动工作项所需的创建时间和参数。因此,每隔一秒,您就会添加一个新数据,并且会有一个线程工作者根据此队列触发事件。但是,您仍然没有机会在您说启动它的时候正确启动代码。

答案 1 :(得分:0)

也许创建一个名为methodBacklog的int,当你的计时器滴答时,将它递增5(或者你想要调用你的函数多次)。

然后你的方法应该在tick发生时触发,但是当methodBacklog&gt; 0.然后,无论何时完成一个方法调用(在webservise之后)都执行methodBacklog--(即将methodBacklog减1)。

这应该确保每一次你想要它被执行,将被执行:)