c# - 在计时器滴答上执行多个线程
c# - Execute multiple threads on timer tick
我有一个程序,它有一个每秒滴答作响的计时器,每次滴答作响我都需要多次执行一个方法。我想在自己的线程中调用每个方法。我调用的方法做了很多工作并以网络服务调用结束,因此可能需要一些时间才能完成(0-30 秒)。我不需要收集响应,所以它基本上是即刻即忘。
问题是如果该方法需要被调用,例如每秒调用 5 次,它只会被调用 1-2 次,就像其他的一样被忽略,因为一个新的计时器滴答将被触发。
我正在使用 .net 3.5、winforms 和 ThreadPool.QueueUserWorkItem
知道如何确保在每个计时器滴答时执行所有方法调用吗?
如果需要,我可以 post 源代码。
谢谢
也许创建一个名为 methodBacklog 的 int,当你的计时器计时时,将它递增 5(或者你想调用你的函数的次数)。
那么你的方法应该不是在 tick 发生时触发,而是在 methodBacklog > 0 时触发。然后每当你完成一个方法调用(在 webservise 之后)做 methodBacklog--(即,将 methodBacklog 减一)。
那应该确保每次你想要它被执行时,都会被执行:)
多线程环境中的主要问题是您无法保证您启动的工作项会在您启动的那一刻执行。
线程冻结的原因有很多:具有更高优先级的新线程、CPU错误、异常等等。因此,即使您使用 ThreadPool.QueueUserWorkItem
开始工作,也不能保证 ThreadPool
会以这种方式正确执行它。
首先要注意的是ThreadPool.QueueUserWorkItem
并不是每次都创建一个新线程。 ThreadPool
很有可能会等待现有线程完成其工作,然后再次使用它。默认情况下,ThreadPool
使用的内部线程数量等于机器上的内核数量 - 这种方法最大限度地减少了线程之间的上下文切换。
其次,如果你说工作线程需要做的很长,并且你每秒创建5个新请求,用户机器很快就会出现饥饿问题 - 会有很多工作使用固定数量的线程执行的项目,您的应用程序将在上下文切换中死亡。
所以我的建议是对工作项使用 FIFO
队列,存储创建时间和启动工作项所需的参数。所以每一秒你都会在那里添加一个新数据,并且会有一个线程工作者根据这个队列触发事件。但是仍然没有机会让您的代码在您说的启动时间准确启动。
我有一个程序,它有一个每秒滴答作响的计时器,每次滴答作响我都需要多次执行一个方法。我想在自己的线程中调用每个方法。我调用的方法做了很多工作并以网络服务调用结束,因此可能需要一些时间才能完成(0-30 秒)。我不需要收集响应,所以它基本上是即刻即忘。
问题是如果该方法需要被调用,例如每秒调用 5 次,它只会被调用 1-2 次,就像其他的一样被忽略,因为一个新的计时器滴答将被触发。
我正在使用 .net 3.5、winforms 和 ThreadPool.QueueUserWorkItem
知道如何确保在每个计时器滴答时执行所有方法调用吗?
如果需要,我可以 post 源代码。
谢谢
也许创建一个名为 methodBacklog 的 int,当你的计时器计时时,将它递增 5(或者你想调用你的函数的次数)。
那么你的方法应该不是在 tick 发生时触发,而是在 methodBacklog > 0 时触发。然后每当你完成一个方法调用(在 webservise 之后)做 methodBacklog--(即,将 methodBacklog 减一)。
那应该确保每次你想要它被执行时,都会被执行:)
多线程环境中的主要问题是您无法保证您启动的工作项会在您启动的那一刻执行。
线程冻结的原因有很多:具有更高优先级的新线程、CPU错误、异常等等。因此,即使您使用 ThreadPool.QueueUserWorkItem
开始工作,也不能保证 ThreadPool
会以这种方式正确执行它。
首先要注意的是ThreadPool.QueueUserWorkItem
并不是每次都创建一个新线程。 ThreadPool
很有可能会等待现有线程完成其工作,然后再次使用它。默认情况下,ThreadPool
使用的内部线程数量等于机器上的内核数量 - 这种方法最大限度地减少了线程之间的上下文切换。
其次,如果你说工作线程需要做的很长,并且你每秒创建5个新请求,用户机器很快就会出现饥饿问题 - 会有很多工作使用固定数量的线程执行的项目,您的应用程序将在上下文切换中死亡。
所以我的建议是对工作项使用 FIFO
队列,存储创建时间和启动工作项所需的参数。所以每一秒你都会在那里添加一个新数据,并且会有一个线程工作者根据这个队列触发事件。但是仍然没有机会让您的代码在您说的启动时间准确启动。