如何确保定期调用某些方法?

时间:2013-11-22 00:40:51

标签: c# .net multithreading threadpool

System.Threading.Timer类允许您定期调用方法:指定的方法在ThreadPool的线程上执行。但是,如果需要执行高优先级的定期任务,如果ThreadPool中没有可用的线程,则无法执行此任务。

上述问题的解决方案可能是使用简单的后台线程和Thread.Sleep方法而不是System.Threading.Timer。还有其他方法可以解决这个问题吗?那么为什么System.Threading.Timer类使用ThreadPool

UPDATE。例如,假设您的应用程序需要处理以不同优先级为特征的不同类别的活动。

  • 定期活动持续时间很短,但它们具有最高优先级,因为它们确保了应用程序的正常运行,因此很可能存在可用的线程到完成它们。应用程序启动时可以启动此类活动。
  • 非周期性任务的持续时间可能更长。例如:从远程客户端请求的处理任务。这些活动的到达时间可能是随机的,因此在这种情况下使用ThreadPool是有意义的。

以下是一些定期活动的例子。

  1. 应用程序需要定期检查您的互联网连接是否正常,然后定期向服务器发送请求。
  2. 客户需要定期检查某些服务器是否已启动并运行。
  3. 服务器希望定期检查与其客户端的连接,以便关闭较少使用的连接。
  4. 当有不同优先级的任务时,使用ThreadPool管理所有这些异构任务是否正确?或者,该池是否应该用于处理相同类型的活动?

    我应该何时使用专用线程来处理定期任务?什么时候使用System.Threading.Timer类更有意义?

    特别是:什么时候不应该使用System.Threading.Timer类来处理定期任务?

2 个答案:

答案 0 :(得分:2)

通常,搞乱线程优先级是一个非常糟糕的想法(例如,在单处理器机器上,如果在高优先级线程上运行的代码消耗100%cpu,则可能导致机器无响应,因为线程永远不会被抢占)。

假设您忽略了上述内容,那么一种方法是启动一个线程并设置它的优先级,并使用它来定期进行重要的处理。例如,

class Program
    {
        static readonly object Locker = new object();
        static void Main(string[] args)
        {
            var importantThread = new Thread(o =>
            {
                while (true)
                {
                    lock (Locker)
                    {
                        Monitor.Wait(Locker, TimeSpan.FromSeconds(3));
                        // do something really really important

                        // if some condition return;
                    }
                }

            }) {Priority = ThreadPriority.Highest};
            importantThread.Start();

            Console.ReadKey();
        }
    }

答案 1 :(得分:0)

我取决于您要执行的任务/活动的类型。

在我看来,我只会使用线程和线程睡眠,如果它是某种实时任务,例如。在非常精确的时间从某些硬件中检索值。

当使用线程池,作为定时器和并行任务时,你可能会在每次调用时滑动一点。

我认为您指定的方案对于以高优先级或非常精确的时间范围运行并不重要。

因此,对于包括你在内的所有其他场景,我只会使用任务或计时器。